diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cd967fc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8ca517d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "nuget" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml new file mode 100644 index 0000000..6617470 --- /dev/null +++ b/.github/workflows/packages.yml @@ -0,0 +1,240 @@ +name: Elsa Studio 3 Packages +on: + workflow_dispatch: + push: + branches: + - 'main' + - 'vnext' + - 'bug/*' + - 'enh/*' + - 'feature/*' + - 'issue/*' + - 'patch/*' + - 'rc/*' + - 'develop/*' + release: + types: [ prereleased, published ] +env: + base_version: '3.5.0' + nuget_feed_feedzio: 'https://f.feedz.io/elsa-workflows/elsa-3/nuget/index.json' + nuget_feed_nuget: 'https://api.nuget.org/v3/index.json' + npm_feed_feedzio: 'https://f.feedz.io/elsa-workflows/elsa-3/npm/' + npm_feed_npm: 'https://registry.npmjs.org/' + +jobs: + build: + name: Build packages + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Extract branch name + run: | + BRANCH_NAME=${{ github.ref }} # e.g., refs/heads/main + BRANCH_NAME=${BRANCH_NAME#refs/heads/} # remove the refs/heads/ prefix + # Extract the last part after the last slash of the branch name, if any, e.g., feature/issue-123 -> issue-123 and use it as the version prefix. + PACKAGE_PREFIX=$(echo $BRANCH_NAME | rev | cut -d/ -f1 | rev | tr '_' '-') + + # If the branch name is main, use the preview version. Otherwise, use the branch name as the version prefix. + if [[ "${BRANCH_NAME}" == "main" || "${BRANCH_NAME}" =~ ^rc/ || "${BRANCH_NAME}" =~ ^develop/ ]]; then + PACKAGE_PREFIX="preview" + fi + + echo "Ref: ${{ github.ref }}" + echo "Branch name: ${BRANCH_NAME}" + echo "Package prefix: ${PACKAGE_PREFIX}" + echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITHUB_ENV + echo "PACKAGE_PREFIX=${PACKAGE_PREFIX}" >> $GITHUB_ENV + - name: Checkout + uses: actions/checkout@v3 + - name: Verify commit exists in remote branch + run: | + if [[ "${{ github.ref }}" == refs/tags/* && "${{ github.event_name }}" == "release" && ("${{ github.event.action }}" == "published" || "${{ github.event.action }}" == "prereleased") ]]; then + git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/* + git branch --remote --contains | grep origin/develop/3.5.0 + else + git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/* + git branch --remote --contains | grep origin/${BRANCH_NAME} + fi + - name: Set VERSION variable + run: | + if [[ "${{ github.ref }}" == refs/tags/* && "${{ github.event_name }}" == "release" && ("${{ github.event.action }}" == "published" || "${{ github.event.action }}" == "prereleased") ]]; then + TAG_NAME=${{ github.ref }} # e.g., refs/tags/3.0.0 + TAG_NAME=${TAG_NAME#refs/tags/} # remove the refs/tags/ prefix + echo "VERSION=${TAG_NAME}" >> $GITHUB_ENV + else + echo "VERSION=${{env.base_version}}-${PACKAGE_PREFIX}.${{github.run_number}}" >> $GITHUB_ENV + fi + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.x + - name: Build workflow designer client assets + working-directory: ./src/modules/Elsa.Studio.Workflows.Designer/ClientLib + run: | + npm install --force + npm run build + - name: Build DOM interop client assets + working-directory: ./src/framework/Elsa.Studio.DomInterop/ClientLib + run: | + npm install --force + npm run build + - name: Build nuget packages + run: dotnet build Elsa.Studio.sln --configuration Release /p:Version=${VERSION} + - name: Test + run: dotnet test Elsa.Studio.sln --configuration Release /p:Version=${VERSION} --no-build + - name: Pack nuget packages + run: dotnet pack Elsa.Studio.sln --configuration Release /p:Version=${VERSION} /p:PackageOutputPath=$(pwd)/packages/nuget + - name: Publish Custom Elements packages # This generates client assets that we then package as an NPM package. + run: dotnet publish ./src/hosts/Elsa.Studio.Host.CustomElements --configuration Release -o ./packages/wasm /p:Version=${VERSION} -f net8.0 + + # Pack npm wasm package + - name: Pack elsa-studio-wasm npm package + run: | + cp ./packages/wasm/npm/package.json ./packages/wasm/wwwroot/package.json # Copy the package.json file from the NPM package to the wwwroot folder. + cd ./packages/wasm/wwwroot + npm version $VERSION --allow-same-version + npm pack + + # Build npm react wrapper package + - name: Pack elsa-studio-wasm-react npm package + run: | + cd ./src/wrappers/wrappers/react-wrapper + npm version $VERSION --allow-same-version + npm run build + npm pack + + # Upload nuget packages + - name: Upload nuget packages + uses: actions/upload-artifact@v4 + with: + name: elsa-studio-nuget-packages + path: ./packages/nuget/*nupkg + + # Upload npm wasm package + - name: Upload npm wasm package + uses: actions/upload-artifact@v4 + with: + name: elsa-studio-npm-packages + path: ./packages/wasm/wwwroot/*.tgz + + # Upload npm react wrapper package + - name: Upload npm react wrapper package + uses: actions/upload-artifact@v4 + with: + name: elsa-studio-npm-react-packages + path: ./src/wrappers/wrappers/react-wrapper/*.tgz + + publish_npm_preview_feedzio: + name: Publish npm packages to feedz.io + needs: build + runs-on: ubuntu-latest + timeout-minutes: 10 + if: ${{ github.event_name == 'release' || github.event_name == 'push'}} + steps: + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.12.1 + registry-url: ${{ env.npm_feed_feedzio }} + + - name: Download npm Packages + uses: actions/download-artifact@v4 + with: + name: elsa-studio-npm-packages + path: elsa-studio-npm-packages + + - name: Publish npm packages to feedz.io + run: | + for file in ./elsa-studio-npm-packages/*.tgz + do + npm publish "$file" --access public + done + env: + NODE_AUTH_TOKEN: ${{secrets.FEEDZ_API_KEY_BASE64}} + + - name: Download npm react Packages + uses: actions/download-artifact@v4 + with: + name: elsa-studio-npm-react-packages + path: elsa-studio-npm-react-packages + + - name: Publish npm react packages to feedz.io + run: | + for file in ./elsa-studio-npm-react-packages/*.tgz + do + npm publish "$file" --access public + done + env: + NODE_AUTH_TOKEN: ${{secrets.FEEDZ_API_KEY_BASE64}} + + publish_npm_npm: + name: Publish npm packages to npmjs.com + needs: build + runs-on: ubuntu-latest + timeout-minutes: 10 + if: ${{ github.event_name == 'release' && github.event.action == 'published' }} + steps: + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.12.1 + registry-url: ${{ env.npm_feed_npm }} + + - name: Download npm Packages + uses: actions/download-artifact@v4 + with: + name: elsa-studio-npm-packages + path: elsa-studio-npm-packages + + - run: | + for file in ./elsa-studio-npm-packages/*.tgz + do + npm publish "$file" --access public + done + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_API_KEY }} + + - name: Download npm react Packages + uses: actions/download-artifact@v4 + with: + name: elsa-studio-npm-react-packages + path: elsa-studio-npm-react-packages + + - run: | + for file in ./elsa-studio-npm-react-packages/*.tgz + do + npm publish "$file" --access public + done + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_API_KEY }} + + publish_nuget_preview_feedzio: + name: Publish nuget packages to feedz.io + needs: build + runs-on: ubuntu-latest + timeout-minutes: 10 + if: ${{ github.event_name == 'release' || github.event_name == 'push'}} + steps: + - name: Download Packages + uses: actions/download-artifact@v4 + with: + name: elsa-studio-nuget-packages + path: elsa-studio-nuget-packages + + - name: Publish to feedz.io + run: dotnet nuget push ./elsa-studio-nuget-packages/*.nupkg -k ${{ secrets.FEEDZ_API_KEY }} -s ${{ env.nuget_feed_feedzio }} --skip-duplicate + + publish_nuget_nuget: + name: Publish to nuget.org + needs: build + runs-on: ubuntu-latest + timeout-minutes: 10 + if: ${{ github.event_name == 'release' && github.event.action == 'published' }} + steps: + - name: Download Packages + uses: actions/download-artifact@v4 + with: + name: elsa-studio-nuget-packages + path: elsa-studio-nuget-packages + + - name: Publish to nuget.org + run: dotnet nuget push ./elsa-studio-nuget-packages/*.nupkg -k ${{ secrets.NUGET_API_KEY }} -s ${{ env.nuget_feed_nuget }} --skip-duplicate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..464d916 --- /dev/null +++ b/.gitignore @@ -0,0 +1,168 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates +.DS_Store + +# Release output from CustomElements - Wasm +src/hosts/Elsa.Studio.Host.CustomElements/wasm + +# React public folder +samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/public + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# Rider is a cross-platform .NET IDE +.idea/ + +# DotCover is a Code Coverage Tool +*.dotCover + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +bower_components/ + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# OpenCover UI analysis results +OpenCover/ + +# MSBuild Binary and Structured Log +*.binlog + +# Local History for Visual Studio +.localhistory/ + +src/modules/**/wwwroot/ +src/framework/**/wwwroot/ +src/modules/Elsa.Studio.Workflows.Designer/ClientLib/package-lock.json +src/modules/Elsa.Studio.DomInterop/ClientLib/package-lock.json +src/framework/Elsa.Studio.DomInterop/ClientLib/package-lock.json + +src/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/package-lock.json + +src/wrappers/.npmrc +.vs \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..089dc31 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,32 @@ + + + net8.0;net9.0 + latest + Elsa Workflows Community + 2023 + https://github.com/elsa-workflows/elsa-studio + https://github.com/elsa-workflows/elsa-studio + git + enable + enable + MIT + icon.png + + + https://v3.elsaworkflows.io/nuget-icon.png + + true + Default + latest + + + true + snupkg + true + + + + + + + \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..91c3cee --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,62 @@ + + + true + false + + + 3.5.0 + 9.0.8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Elsa.Studio-Core.sln b/Elsa.Studio-Core.sln new file mode 100644 index 0000000..738f724 --- /dev/null +++ b/Elsa.Studio-Core.sln @@ -0,0 +1,287 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{875A7E2E-4B7C-4AF0-A71E-3980B73AF363}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution", "solution", "{C5E5655F-9B0D-4A93-9D0D-58216E8DE9C1}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + README.md = README.md + LICENSE = LICENSE + NuGet.Config = NuGet.Config + Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{B7464426-9B29-4CF9-9B9C-6941D9E99060}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{0D17508F-2117-49C0-B661-4F3118C8126C}" + ProjectSection(SolutionItems) = preProject + .github\workflows\packages.yml = .github\workflows\packages.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{D66B9A40-8608-46F3-9868-625C50EACE43}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Host.Wasm", "src\hosts\Elsa.Studio.Host.Wasm\Elsa.Studio.Host.Wasm.csproj", "{B61B3A06-5AF3-4007-9D22-18A319549156}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Host.Server", "src\hosts\Elsa.Studio.Host.Server\Elsa.Studio.Host.Server.csproj", "{CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "framework", "framework", "{C5288F1B-F4E5-423C-AEE8-049996613668}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Shell", "src\framework\Elsa.Studio.Shell\Elsa.Studio.Shell.csproj", "{7F1322EB-7314-47A7-9F03-7D8CB31097C8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.DomInterop", "src\framework\Elsa.Studio.DomInterop\Elsa.Studio.DomInterop.csproj", "{B15E4EAF-62C3-4D3B-B12D-4119D517728C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Shared", "src\framework\Elsa.Studio.Shared\Elsa.Studio.Shared.csproj", "{21B6A662-8DB2-452E-95E7-3E4227D1544A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bundles", "bundles", "{6BF88129-D74E-46FA-89A4-29B9FBAEC241}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio", "src\bundles\Elsa.Studio\Elsa.Studio.csproj", "{6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Host.CustomElements", "src\hosts\Elsa.Studio.Host.CustomElements\Elsa.Studio.Host.CustomElements.csproj", "{8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.ActivityPortProviders", "src\modules\Elsa.Studio.ActivityPortProviders\Elsa.Studio.ActivityPortProviders.csproj", "{B831EE86-F713-4466-B91D-FA66EDCC2E30}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Core", "src\framework\Elsa.Studio.Core\Elsa.Studio.Core.csproj", "{C5D998F4-4523-49AF-9F0F-7BCDACA58790}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Core.BlazorServer", "src\framework\Elsa.Studio.Core.BlazorServer\Elsa.Studio.Core.BlazorServer.csproj", "{2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Core.BlazorWasm", "src\framework\Elsa.Studio.Core.BlazorWasm\Elsa.Studio.Core.BlazorWasm.csproj", "{565B61D8-C67A-449B-BAE6-BEAC95E52B8F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Counter", "src\modules\Elsa.Studio.Counter\Elsa.Studio.Counter.csproj", "{5DE5EFD1-00C0-4797-BFC3-8989ACF52165}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Dashboard", "src\modules\Elsa.Studio.Dashboard\Elsa.Studio.Dashboard.csproj", "{5161EB5E-9301-4A43-A7CC-CDC665CD7B93}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Environments", "src\modules\Elsa.Studio.Environments\Elsa.Studio.Environments.csproj", "{7A30797E-A1BF-4128-BB23-D8B00CDD59FD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Login", "src\modules\Elsa.Studio.Login\Elsa.Studio.Login.csproj", "{AC76C31B-75F0-473C-8F96-DE77AFF76536}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Login.BlazorServer", "src\modules\Elsa.Studio.Login.BlazorServer\Elsa.Studio.Login.BlazorServer.csproj", "{B5CF2E45-29A0-4101-90C3-2E6C31142F8F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Login.BlazorWasm", "src\modules\Elsa.Studio.Login.BlazorWasm\Elsa.Studio.Login.BlazorWasm.csproj", "{5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Secrets", "src\modules\Elsa.Studio.Secrets\Elsa.Studio.Secrets.csproj", "{00956738-21BD-4D78-B9AF-67CD0A8B6440}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Security", "src\modules\Elsa.Studio.Security\Elsa.Studio.Security.csproj", "{435D5AF5-D06C-47A6-94B0-9B31016250DC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.UIHints", "src\modules\Elsa.Studio.UIHints\Elsa.Studio.UIHints.csproj", "{C15D23AC-26CA-447D-B441-75407FD79A6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Webhooks", "src\modules\Elsa.Studio.Webhooks\Elsa.Studio.Webhooks.csproj", "{C18714D2-7205-491D-AD2E-154876F7A77F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Workflows.Core", "src\modules\Elsa.Studio.Workflows.Core\Elsa.Studio.Workflows.Core.csproj", "{F85F11D4-8D22-4119-B212-2CD19DDFB0B4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Workflows", "src\modules\Elsa.Studio.Workflows\Elsa.Studio.Workflows.csproj", "{AF48A447-22AF-4C94-8C5D-2B47FD90484C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Workflows.Designer", "src\modules\Elsa.Studio.Workflows.Designer\Elsa.Studio.Workflows.Designer.csproj", "{E55917F6-388C-47FB-922B-ADE3D1AF5D6E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.WorkflowContexts", "src\modules\Elsa.Studio.WorkflowContexts\Elsa.Studio.WorkflowContexts.csproj", "{2C40C5CB-634B-45DA-8F65-F0D460C1CB63}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{D2254084-0C4A-42F3-A2D9-A2C9BCE1114E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorApp1", "samples\BlazorApp1\BlazorApp1.csproj", "{FAE56DEE-A51D-4FC7-AF42-D298BE59D8EE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{F4B408E1-5169-4FA9-B2D7-2377634C4DEE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Api.Client", "..\..\elsa-core\main\src\clients\Elsa.Api.Client\Elsa.Api.Client.csproj", "{26ECE061-0F39-4945-8356-EF14E67A8F39}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Agents", "src\modules\Elsa.Studio.Agents\Elsa.Studio.Agents.csproj", "{BDAB9EEA-3083-41D8-933A-E848D346EB2E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Secrets.Models", "..\..\elsa-core\main\src\modules\Elsa.Secrets.Models\Elsa.Secrets.Models.csproj", "{C3681176-1FB1-4B63-BEC7-34DB9813E88D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Localization", "src\modules\Elsa.Studio.Localization\Elsa.Studio.Localization.csproj", "{69695115-160C-498F-A6FE-528A908391AF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Localization.BlazorServer", "src\modules\Elsa.Studio.Localization.BlazorServer\Elsa.Studio.Localization.BlazorServer.csproj", "{A37FA04C-BDEE-4790-9433-9BAE05C06B4D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Localization.BlazorWasm", "src\modules\Elsa.Studio.Localization.BlazorWasm\Elsa.Studio.Localization.BlazorWasm.csproj", "{2B7AB46C-F269-4FF5-B6B2-C73CF1C772DB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Translations", "src\framework\Elsa.Studio.Translations\Elsa.Studio.Translations.csproj", "{DEFD3B1C-BCD1-4442-BF4B-6517FF19ECBC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "elsa", "elsa", "{7A0B2C03-0725-499E-B739-3FB41983B679}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Api.Client", "..\..\elsa-core\3.5.0\src\clients\Elsa.Api.Client\Elsa.Api.Client.csproj", "{CED02683-4B65-496B-B0B6-2EB0F1F179F9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B61B3A06-5AF3-4007-9D22-18A319549156}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B61B3A06-5AF3-4007-9D22-18A319549156}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B61B3A06-5AF3-4007-9D22-18A319549156}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B61B3A06-5AF3-4007-9D22-18A319549156}.Release|Any CPU.Build.0 = Release|Any CPU + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}.Release|Any CPU.Build.0 = Release|Any CPU + {7F1322EB-7314-47A7-9F03-7D8CB31097C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F1322EB-7314-47A7-9F03-7D8CB31097C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F1322EB-7314-47A7-9F03-7D8CB31097C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F1322EB-7314-47A7-9F03-7D8CB31097C8}.Release|Any CPU.Build.0 = Release|Any CPU + {B15E4EAF-62C3-4D3B-B12D-4119D517728C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B15E4EAF-62C3-4D3B-B12D-4119D517728C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B15E4EAF-62C3-4D3B-B12D-4119D517728C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B15E4EAF-62C3-4D3B-B12D-4119D517728C}.Release|Any CPU.Build.0 = Release|Any CPU + {21B6A662-8DB2-452E-95E7-3E4227D1544A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {21B6A662-8DB2-452E-95E7-3E4227D1544A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {21B6A662-8DB2-452E-95E7-3E4227D1544A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {21B6A662-8DB2-452E-95E7-3E4227D1544A}.Release|Any CPU.Build.0 = Release|Any CPU + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}.Release|Any CPU.Build.0 = Release|Any CPU + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}.Release|Any CPU.Build.0 = Release|Any CPU + {B831EE86-F713-4466-B91D-FA66EDCC2E30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B831EE86-F713-4466-B91D-FA66EDCC2E30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B831EE86-F713-4466-B91D-FA66EDCC2E30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B831EE86-F713-4466-B91D-FA66EDCC2E30}.Release|Any CPU.Build.0 = Release|Any CPU + {C5D998F4-4523-49AF-9F0F-7BCDACA58790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5D998F4-4523-49AF-9F0F-7BCDACA58790}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5D998F4-4523-49AF-9F0F-7BCDACA58790}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5D998F4-4523-49AF-9F0F-7BCDACA58790}.Release|Any CPU.Build.0 = Release|Any CPU + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}.Release|Any CPU.Build.0 = Release|Any CPU + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F}.Release|Any CPU.Build.0 = Release|Any CPU + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165}.Release|Any CPU.Build.0 = Release|Any CPU + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93}.Release|Any CPU.Build.0 = Release|Any CPU + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD}.Release|Any CPU.Build.0 = Release|Any CPU + {AC76C31B-75F0-473C-8F96-DE77AFF76536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC76C31B-75F0-473C-8F96-DE77AFF76536}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC76C31B-75F0-473C-8F96-DE77AFF76536}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC76C31B-75F0-473C-8F96-DE77AFF76536}.Release|Any CPU.Build.0 = Release|Any CPU + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F}.Release|Any CPU.Build.0 = Release|Any CPU + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}.Release|Any CPU.Build.0 = Release|Any CPU + {00956738-21BD-4D78-B9AF-67CD0A8B6440}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00956738-21BD-4D78-B9AF-67CD0A8B6440}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00956738-21BD-4D78-B9AF-67CD0A8B6440}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00956738-21BD-4D78-B9AF-67CD0A8B6440}.Release|Any CPU.Build.0 = Release|Any CPU + {435D5AF5-D06C-47A6-94B0-9B31016250DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {435D5AF5-D06C-47A6-94B0-9B31016250DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {435D5AF5-D06C-47A6-94B0-9B31016250DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {435D5AF5-D06C-47A6-94B0-9B31016250DC}.Release|Any CPU.Build.0 = Release|Any CPU + {C15D23AC-26CA-447D-B441-75407FD79A6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C15D23AC-26CA-447D-B441-75407FD79A6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C15D23AC-26CA-447D-B441-75407FD79A6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C15D23AC-26CA-447D-B441-75407FD79A6A}.Release|Any CPU.Build.0 = Release|Any CPU + {C18714D2-7205-491D-AD2E-154876F7A77F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C18714D2-7205-491D-AD2E-154876F7A77F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C18714D2-7205-491D-AD2E-154876F7A77F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C18714D2-7205-491D-AD2E-154876F7A77F}.Release|Any CPU.Build.0 = Release|Any CPU + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4}.Release|Any CPU.Build.0 = Release|Any CPU + {AF48A447-22AF-4C94-8C5D-2B47FD90484C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF48A447-22AF-4C94-8C5D-2B47FD90484C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF48A447-22AF-4C94-8C5D-2B47FD90484C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF48A447-22AF-4C94-8C5D-2B47FD90484C}.Release|Any CPU.Build.0 = Release|Any CPU + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E}.Release|Any CPU.Build.0 = Release|Any CPU + {2C40C5CB-634B-45DA-8F65-F0D460C1CB63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C40C5CB-634B-45DA-8F65-F0D460C1CB63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C40C5CB-634B-45DA-8F65-F0D460C1CB63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C40C5CB-634B-45DA-8F65-F0D460C1CB63}.Release|Any CPU.Build.0 = Release|Any CPU + {FAE56DEE-A51D-4FC7-AF42-D298BE59D8EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FAE56DEE-A51D-4FC7-AF42-D298BE59D8EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FAE56DEE-A51D-4FC7-AF42-D298BE59D8EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FAE56DEE-A51D-4FC7-AF42-D298BE59D8EE}.Release|Any CPU.Build.0 = Release|Any CPU + {26ECE061-0F39-4945-8356-EF14E67A8F39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26ECE061-0F39-4945-8356-EF14E67A8F39}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26ECE061-0F39-4945-8356-EF14E67A8F39}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26ECE061-0F39-4945-8356-EF14E67A8F39}.Release|Any CPU.Build.0 = Release|Any CPU + {BDAB9EEA-3083-41D8-933A-E848D346EB2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDAB9EEA-3083-41D8-933A-E848D346EB2E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDAB9EEA-3083-41D8-933A-E848D346EB2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BDAB9EEA-3083-41D8-933A-E848D346EB2E}.Release|Any CPU.Build.0 = Release|Any CPU + {C3681176-1FB1-4B63-BEC7-34DB9813E88D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3681176-1FB1-4B63-BEC7-34DB9813E88D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3681176-1FB1-4B63-BEC7-34DB9813E88D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3681176-1FB1-4B63-BEC7-34DB9813E88D}.Release|Any CPU.Build.0 = Release|Any CPU + {69695115-160C-498F-A6FE-528A908391AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69695115-160C-498F-A6FE-528A908391AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69695115-160C-498F-A6FE-528A908391AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69695115-160C-498F-A6FE-528A908391AF}.Release|Any CPU.Build.0 = Release|Any CPU + {A37FA04C-BDEE-4790-9433-9BAE05C06B4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A37FA04C-BDEE-4790-9433-9BAE05C06B4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A37FA04C-BDEE-4790-9433-9BAE05C06B4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A37FA04C-BDEE-4790-9433-9BAE05C06B4D}.Release|Any CPU.Build.0 = Release|Any CPU + {2B7AB46C-F269-4FF5-B6B2-C73CF1C772DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2B7AB46C-F269-4FF5-B6B2-C73CF1C772DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2B7AB46C-F269-4FF5-B6B2-C73CF1C772DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2B7AB46C-F269-4FF5-B6B2-C73CF1C772DB}.Release|Any CPU.Build.0 = Release|Any CPU + {DEFD3B1C-BCD1-4442-BF4B-6517FF19ECBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DEFD3B1C-BCD1-4442-BF4B-6517FF19ECBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DEFD3B1C-BCD1-4442-BF4B-6517FF19ECBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DEFD3B1C-BCD1-4442-BF4B-6517FF19ECBC}.Release|Any CPU.Build.0 = Release|Any CPU + {CED02683-4B65-496B-B0B6-2EB0F1F179F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CED02683-4B65-496B-B0B6-2EB0F1F179F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CED02683-4B65-496B-B0B6-2EB0F1F179F9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CED02683-4B65-496B-B0B6-2EB0F1F179F9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} = {875A7E2E-4B7C-4AF0-A71E-3980B73AF363} + {D66B9A40-8608-46F3-9868-625C50EACE43} = {875A7E2E-4B7C-4AF0-A71E-3980B73AF363} + {B61B3A06-5AF3-4007-9D22-18A319549156} = {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6} = {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} + {C5288F1B-F4E5-423C-AEE8-049996613668} = {875A7E2E-4B7C-4AF0-A71E-3980B73AF363} + {7F1322EB-7314-47A7-9F03-7D8CB31097C8} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {B15E4EAF-62C3-4D3B-B12D-4119D517728C} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {21B6A662-8DB2-452E-95E7-3E4227D1544A} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {6BF88129-D74E-46FA-89A4-29B9FBAEC241} = {875A7E2E-4B7C-4AF0-A71E-3980B73AF363} + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D} = {6BF88129-D74E-46FA-89A4-29B9FBAEC241} + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8} = {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} + {C5D998F4-4523-49AF-9F0F-7BCDACA58790} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {B831EE86-F713-4466-B91D-FA66EDCC2E30} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {AF48A447-22AF-4C94-8C5D-2B47FD90484C} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {AC76C31B-75F0-473C-8F96-DE77AFF76536} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {00956738-21BD-4D78-B9AF-67CD0A8B6440} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {435D5AF5-D06C-47A6-94B0-9B31016250DC} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {C15D23AC-26CA-447D-B441-75407FD79A6A} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {C18714D2-7205-491D-AD2E-154876F7A77F} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {2C40C5CB-634B-45DA-8F65-F0D460C1CB63} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {FAE56DEE-A51D-4FC7-AF42-D298BE59D8EE} = {D2254084-0C4A-42F3-A2D9-A2C9BCE1114E} + {26ECE061-0F39-4945-8356-EF14E67A8F39} = {F4B408E1-5169-4FA9-B2D7-2377634C4DEE} + {BDAB9EEA-3083-41D8-933A-E848D346EB2E} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {C3681176-1FB1-4B63-BEC7-34DB9813E88D} = {F4B408E1-5169-4FA9-B2D7-2377634C4DEE} + {69695115-160C-498F-A6FE-528A908391AF} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {A37FA04C-BDEE-4790-9433-9BAE05C06B4D} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {2B7AB46C-F269-4FF5-B6B2-C73CF1C772DB} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {DEFD3B1C-BCD1-4442-BF4B-6517FF19ECBC} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {CED02683-4B65-496B-B0B6-2EB0F1F179F9} = {7A0B2C03-0725-499E-B739-3FB41983B679} + EndGlobalSection +EndGlobal diff --git a/Elsa.Studio-Core.sln.DotSettings b/Elsa.Studio-Core.sln.DotSettings new file mode 100644 index 0000000..410d494 --- /dev/null +++ b/Elsa.Studio-Core.sln.DotSettings @@ -0,0 +1,12 @@ + + IF_OWNER_IS_SINGLE_LINE + UI + True + True + True + True + True + True + True + True + True \ No newline at end of file diff --git a/Elsa.Studio.sln b/Elsa.Studio.sln new file mode 100644 index 0000000..ca16b88 --- /dev/null +++ b/Elsa.Studio.sln @@ -0,0 +1,264 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35327.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{875A7E2E-4B7C-4AF0-A71E-3980B73AF363}" + ProjectSection(SolutionItems) = preProject + src\Directory.Build.props = src\Directory.Build.props + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution", "solution", "{C5E5655F-9B0D-4A93-9D0D-58216E8DE9C1}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props + LICENSE = LICENSE + NuGet.Config = NuGet.Config + README.md = README.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{B7464426-9B29-4CF9-9B9C-6941D9E99060}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{0D17508F-2117-49C0-B661-4F3118C8126C}" + ProjectSection(SolutionItems) = preProject + .github\workflows\packages.yml = .github\workflows\packages.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hosts", "hosts", "{2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{D66B9A40-8608-46F3-9868-625C50EACE43}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Host.Wasm", "src\hosts\Elsa.Studio.Host.Wasm\Elsa.Studio.Host.Wasm.csproj", "{B61B3A06-5AF3-4007-9D22-18A319549156}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Host.Server", "src\hosts\Elsa.Studio.Host.Server\Elsa.Studio.Host.Server.csproj", "{CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "framework", "framework", "{C5288F1B-F4E5-423C-AEE8-049996613668}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Shell", "src\framework\Elsa.Studio.Shell\Elsa.Studio.Shell.csproj", "{7F1322EB-7314-47A7-9F03-7D8CB31097C8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.DomInterop", "src\framework\Elsa.Studio.DomInterop\Elsa.Studio.DomInterop.csproj", "{B15E4EAF-62C3-4D3B-B12D-4119D517728C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Shared", "src\framework\Elsa.Studio.Shared\Elsa.Studio.Shared.csproj", "{21B6A662-8DB2-452E-95E7-3E4227D1544A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bundles", "bundles", "{6BF88129-D74E-46FA-89A4-29B9FBAEC241}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio", "src\bundles\Elsa.Studio\Elsa.Studio.csproj", "{6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Host.CustomElements", "src\hosts\Elsa.Studio.Host.CustomElements\Elsa.Studio.Host.CustomElements.csproj", "{8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.ActivityPortProviders", "src\modules\Elsa.Studio.ActivityPortProviders\Elsa.Studio.ActivityPortProviders.csproj", "{B831EE86-F713-4466-B91D-FA66EDCC2E30}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Core", "src\framework\Elsa.Studio.Core\Elsa.Studio.Core.csproj", "{C5D998F4-4523-49AF-9F0F-7BCDACA58790}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Core.BlazorServer", "src\framework\Elsa.Studio.Core.BlazorServer\Elsa.Studio.Core.BlazorServer.csproj", "{2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Core.BlazorWasm", "src\framework\Elsa.Studio.Core.BlazorWasm\Elsa.Studio.Core.BlazorWasm.csproj", "{565B61D8-C67A-449B-BAE6-BEAC95E52B8F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Counter", "src\modules\Elsa.Studio.Counter\Elsa.Studio.Counter.csproj", "{5DE5EFD1-00C0-4797-BFC3-8989ACF52165}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Dashboard", "src\modules\Elsa.Studio.Dashboard\Elsa.Studio.Dashboard.csproj", "{5161EB5E-9301-4A43-A7CC-CDC665CD7B93}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Environments", "src\modules\Elsa.Studio.Environments\Elsa.Studio.Environments.csproj", "{7A30797E-A1BF-4128-BB23-D8B00CDD59FD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Login", "src\modules\Elsa.Studio.Login\Elsa.Studio.Login.csproj", "{AC76C31B-75F0-473C-8F96-DE77AFF76536}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Login.BlazorServer", "src\modules\Elsa.Studio.Login.BlazorServer\Elsa.Studio.Login.BlazorServer.csproj", "{B5CF2E45-29A0-4101-90C3-2E6C31142F8F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Login.BlazorWasm", "src\modules\Elsa.Studio.Login.BlazorWasm\Elsa.Studio.Login.BlazorWasm.csproj", "{5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Secrets", "src\modules\Elsa.Studio.Secrets\Elsa.Studio.Secrets.csproj", "{00956738-21BD-4D78-B9AF-67CD0A8B6440}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Security", "src\modules\Elsa.Studio.Security\Elsa.Studio.Security.csproj", "{435D5AF5-D06C-47A6-94B0-9B31016250DC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.UIHints", "src\modules\Elsa.Studio.UIHints\Elsa.Studio.UIHints.csproj", "{C15D23AC-26CA-447D-B441-75407FD79A6A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Webhooks", "src\modules\Elsa.Studio.Webhooks\Elsa.Studio.Webhooks.csproj", "{C18714D2-7205-491D-AD2E-154876F7A77F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Workflows.Core", "src\modules\Elsa.Studio.Workflows.Core\Elsa.Studio.Workflows.Core.csproj", "{F85F11D4-8D22-4119-B212-2CD19DDFB0B4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Workflows", "src\modules\Elsa.Studio.Workflows\Elsa.Studio.Workflows.csproj", "{AF48A447-22AF-4C94-8C5D-2B47FD90484C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Workflows.Designer", "src\modules\Elsa.Studio.Workflows.Designer\Elsa.Studio.Workflows.Designer.csproj", "{E55917F6-388C-47FB-922B-ADE3D1AF5D6E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.WorkflowContexts", "src\modules\Elsa.Studio.WorkflowContexts\Elsa.Studio.WorkflowContexts.csproj", "{AFF99B0F-8243-449C-8AA3-4A087D3DE575}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Localization", "src\modules\Elsa.Studio.Localization\Elsa.Studio.Localization.csproj", "{F3C53AFF-EBE5-447D-AF4D-136F18761733}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Studio.Localization.BlazorServer", "src\modules\Elsa.Studio.Localization.BlazorServer\Elsa.Studio.Localization.BlazorServer.csproj", "{F5BBEF8A-D75E-442E-A2E7-EEF5F04335A5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Localization.BlazorWasm", "src\modules\Elsa.Studio.Localization.BlazorWasm\Elsa.Studio.Localization.BlazorWasm.csproj", "{DE57FD2C-3874-486A-89B1-D982726A1189}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Translations", "src\framework\Elsa.Studio.Translations\Elsa.Studio.Translations.csproj", "{76C60D97-FA22-4023-BDB3-6BC47D097E40}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Host.HostedWasm", "src\hosts\Elsa.Studio.Host.HostedWasm\Elsa.Studio.Host.HostedWasm.csproj", "{25BA3052-4F17-4D24-9AE9-01FBD75E8804}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B61B3A06-5AF3-4007-9D22-18A319549156}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B61B3A06-5AF3-4007-9D22-18A319549156}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B61B3A06-5AF3-4007-9D22-18A319549156}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B61B3A06-5AF3-4007-9D22-18A319549156}.Release|Any CPU.Build.0 = Release|Any CPU + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6}.Release|Any CPU.Build.0 = Release|Any CPU + {7F1322EB-7314-47A7-9F03-7D8CB31097C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F1322EB-7314-47A7-9F03-7D8CB31097C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F1322EB-7314-47A7-9F03-7D8CB31097C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F1322EB-7314-47A7-9F03-7D8CB31097C8}.Release|Any CPU.Build.0 = Release|Any CPU + {B15E4EAF-62C3-4D3B-B12D-4119D517728C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B15E4EAF-62C3-4D3B-B12D-4119D517728C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B15E4EAF-62C3-4D3B-B12D-4119D517728C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B15E4EAF-62C3-4D3B-B12D-4119D517728C}.Release|Any CPU.Build.0 = Release|Any CPU + {21B6A662-8DB2-452E-95E7-3E4227D1544A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {21B6A662-8DB2-452E-95E7-3E4227D1544A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {21B6A662-8DB2-452E-95E7-3E4227D1544A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {21B6A662-8DB2-452E-95E7-3E4227D1544A}.Release|Any CPU.Build.0 = Release|Any CPU + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D}.Release|Any CPU.Build.0 = Release|Any CPU + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8}.Release|Any CPU.Build.0 = Release|Any CPU + {B831EE86-F713-4466-B91D-FA66EDCC2E30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B831EE86-F713-4466-B91D-FA66EDCC2E30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B831EE86-F713-4466-B91D-FA66EDCC2E30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B831EE86-F713-4466-B91D-FA66EDCC2E30}.Release|Any CPU.Build.0 = Release|Any CPU + {C5D998F4-4523-49AF-9F0F-7BCDACA58790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5D998F4-4523-49AF-9F0F-7BCDACA58790}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5D998F4-4523-49AF-9F0F-7BCDACA58790}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5D998F4-4523-49AF-9F0F-7BCDACA58790}.Release|Any CPU.Build.0 = Release|Any CPU + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48}.Release|Any CPU.Build.0 = Release|Any CPU + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F}.Release|Any CPU.Build.0 = Release|Any CPU + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165}.Release|Any CPU.Build.0 = Release|Any CPU + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93}.Release|Any CPU.Build.0 = Release|Any CPU + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD}.Release|Any CPU.Build.0 = Release|Any CPU + {AC76C31B-75F0-473C-8F96-DE77AFF76536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC76C31B-75F0-473C-8F96-DE77AFF76536}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC76C31B-75F0-473C-8F96-DE77AFF76536}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC76C31B-75F0-473C-8F96-DE77AFF76536}.Release|Any CPU.Build.0 = Release|Any CPU + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F}.Release|Any CPU.Build.0 = Release|Any CPU + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD}.Release|Any CPU.Build.0 = Release|Any CPU + {00956738-21BD-4D78-B9AF-67CD0A8B6440}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00956738-21BD-4D78-B9AF-67CD0A8B6440}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00956738-21BD-4D78-B9AF-67CD0A8B6440}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00956738-21BD-4D78-B9AF-67CD0A8B6440}.Release|Any CPU.Build.0 = Release|Any CPU + {435D5AF5-D06C-47A6-94B0-9B31016250DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {435D5AF5-D06C-47A6-94B0-9B31016250DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {435D5AF5-D06C-47A6-94B0-9B31016250DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {435D5AF5-D06C-47A6-94B0-9B31016250DC}.Release|Any CPU.Build.0 = Release|Any CPU + {C15D23AC-26CA-447D-B441-75407FD79A6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C15D23AC-26CA-447D-B441-75407FD79A6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C15D23AC-26CA-447D-B441-75407FD79A6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C15D23AC-26CA-447D-B441-75407FD79A6A}.Release|Any CPU.Build.0 = Release|Any CPU + {C18714D2-7205-491D-AD2E-154876F7A77F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C18714D2-7205-491D-AD2E-154876F7A77F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C18714D2-7205-491D-AD2E-154876F7A77F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C18714D2-7205-491D-AD2E-154876F7A77F}.Release|Any CPU.Build.0 = Release|Any CPU + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4}.Release|Any CPU.Build.0 = Release|Any CPU + {AF48A447-22AF-4C94-8C5D-2B47FD90484C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF48A447-22AF-4C94-8C5D-2B47FD90484C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF48A447-22AF-4C94-8C5D-2B47FD90484C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF48A447-22AF-4C94-8C5D-2B47FD90484C}.Release|Any CPU.Build.0 = Release|Any CPU + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E}.Release|Any CPU.Build.0 = Release|Any CPU + {AFF99B0F-8243-449C-8AA3-4A087D3DE575}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AFF99B0F-8243-449C-8AA3-4A087D3DE575}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AFF99B0F-8243-449C-8AA3-4A087D3DE575}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AFF99B0F-8243-449C-8AA3-4A087D3DE575}.Release|Any CPU.Build.0 = Release|Any CPU + {F3C53AFF-EBE5-447D-AF4D-136F18761733}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3C53AFF-EBE5-447D-AF4D-136F18761733}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3C53AFF-EBE5-447D-AF4D-136F18761733}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3C53AFF-EBE5-447D-AF4D-136F18761733}.Release|Any CPU.Build.0 = Release|Any CPU + {F5BBEF8A-D75E-442E-A2E7-EEF5F04335A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5BBEF8A-D75E-442E-A2E7-EEF5F04335A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5BBEF8A-D75E-442E-A2E7-EEF5F04335A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5BBEF8A-D75E-442E-A2E7-EEF5F04335A5}.Release|Any CPU.Build.0 = Release|Any CPU + {DE57FD2C-3874-486A-89B1-D982726A1189}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE57FD2C-3874-486A-89B1-D982726A1189}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE57FD2C-3874-486A-89B1-D982726A1189}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE57FD2C-3874-486A-89B1-D982726A1189}.Release|Any CPU.Build.0 = Release|Any CPU + {76C60D97-FA22-4023-BDB3-6BC47D097E40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76C60D97-FA22-4023-BDB3-6BC47D097E40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76C60D97-FA22-4023-BDB3-6BC47D097E40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76C60D97-FA22-4023-BDB3-6BC47D097E40}.Release|Any CPU.Build.0 = Release|Any CPU + {25BA3052-4F17-4D24-9AE9-01FBD75E8804}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25BA3052-4F17-4D24-9AE9-01FBD75E8804}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25BA3052-4F17-4D24-9AE9-01FBD75E8804}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25BA3052-4F17-4D24-9AE9-01FBD75E8804}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} = {875A7E2E-4B7C-4AF0-A71E-3980B73AF363} + {D66B9A40-8608-46F3-9868-625C50EACE43} = {875A7E2E-4B7C-4AF0-A71E-3980B73AF363} + {B61B3A06-5AF3-4007-9D22-18A319549156} = {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} + {CE71F7A2-3AB3-4475-B7F4-CF5128D0A4F6} = {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} + {C5288F1B-F4E5-423C-AEE8-049996613668} = {875A7E2E-4B7C-4AF0-A71E-3980B73AF363} + {7F1322EB-7314-47A7-9F03-7D8CB31097C8} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {B15E4EAF-62C3-4D3B-B12D-4119D517728C} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {21B6A662-8DB2-452E-95E7-3E4227D1544A} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {6BF88129-D74E-46FA-89A4-29B9FBAEC241} = {875A7E2E-4B7C-4AF0-A71E-3980B73AF363} + {6029D546-A5DB-4B75-8DE4-BFB83EB2A24D} = {6BF88129-D74E-46FA-89A4-29B9FBAEC241} + {8A9DBE4A-A03F-44C9-9AB2-74AA973D72A8} = {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} + {B831EE86-F713-4466-B91D-FA66EDCC2E30} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {C5D998F4-4523-49AF-9F0F-7BCDACA58790} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {2FC3CE4B-02D3-4808-828E-F4D84FFD1E48} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {565B61D8-C67A-449B-BAE6-BEAC95E52B8F} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {5DE5EFD1-00C0-4797-BFC3-8989ACF52165} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {5161EB5E-9301-4A43-A7CC-CDC665CD7B93} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {7A30797E-A1BF-4128-BB23-D8B00CDD59FD} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {AC76C31B-75F0-473C-8F96-DE77AFF76536} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {B5CF2E45-29A0-4101-90C3-2E6C31142F8F} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {5A3139DC-0FFB-4B44-8BF1-38F29C6133CD} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {00956738-21BD-4D78-B9AF-67CD0A8B6440} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {435D5AF5-D06C-47A6-94B0-9B31016250DC} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {C15D23AC-26CA-447D-B441-75407FD79A6A} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {C18714D2-7205-491D-AD2E-154876F7A77F} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {F85F11D4-8D22-4119-B212-2CD19DDFB0B4} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {AF48A447-22AF-4C94-8C5D-2B47FD90484C} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {E55917F6-388C-47FB-922B-ADE3D1AF5D6E} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {AFF99B0F-8243-449C-8AA3-4A087D3DE575} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {F3C53AFF-EBE5-447D-AF4D-136F18761733} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {F5BBEF8A-D75E-442E-A2E7-EEF5F04335A5} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {DE57FD2C-3874-486A-89B1-D982726A1189} = {D66B9A40-8608-46F3-9868-625C50EACE43} + {76C60D97-FA22-4023-BDB3-6BC47D097E40} = {C5288F1B-F4E5-423C-AEE8-049996613668} + {25BA3052-4F17-4D24-9AE9-01FBD75E8804} = {2AA1AEE9-017E-4F8B-B5FC-2BEA37E83514} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5B8719CC-CF87-45E1-BE1A-13842F951B28} + EndGlobalSection +EndGlobal diff --git a/Elsa.Studio.sln.DotSettings b/Elsa.Studio.sln.DotSettings new file mode 100644 index 0000000..2c114d9 --- /dev/null +++ b/Elsa.Studio.sln.DotSettings @@ -0,0 +1,13 @@ + + False + JS + UI + True + True + True + True + True + True + True + True + True \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..737c5cd --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Elsa Workflows + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 0000000..85089f0 --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/NuGet.rar b/NuGet.rar new file mode 100644 index 0000000..9779f43 Binary files /dev/null and b/NuGet.rar differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..c8fabe3 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Elsa Studio + + +

+ Elsa Studio workflow designer +

+
+ +[![Nuget](https://img.shields.io/nuget/v/elsa)](https://www.nuget.org/packages/Elsa.Studio.Shell/) +[![Build status](https://github.com/elsa-workflows/elsa-studio/actions/workflows/packages.yml/badge.svg?branch=main)](https://github.com/elsa-workflows/elsa-studio/actions/workflows/packages.yml) +[![Discord](https://img.shields.io/discord/814605913783795763?label=chat&logo=discord)](https://discord.gg/hhChk5H472) +[![Stack Overflow questions](https://img.shields.io/badge/stackoverflow-elsa_workflows-orange.svg)]( http://stackoverflow.com/questions/tagged/elsa-workflows ) +[![Translation status](https://hosted.weblate.org/widget/elsa-studio/svg-badge.svg)](https://hosted.weblate.org/engage/elsa-studio/) + +Elsa Studio is a modular, extensible application framework built with MudBlazor and is used to manage Elsa workflows and related entities. + +## Prerequisites + +- **.NET SDK**: Ensure you have both [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0) and [.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0) SDKs installed. +- **Node.js and npm**: Install [Node.js](https://nodejs.org/) (which includes npm) for the frontend tooling. + +## Setup + +1. **Clone the repository**: `git clone https://github.com/elsa-workflows/elsa-studio.git` +2. **Navigate to the project directory**: `cd elsa-studio` + +## Before you build + +There are some assets that require `NPM` to build the assets prior to the project building. These have been configured to use an MSBUILD pre-build step and should not require any extra +steps but should you run into any issues or want to build these ahead of time, take the following steps + +1. **Navigate to ClientLib folder in Elsa.Studio.DomInterop**: `cd .\src\framework\Elsa.Studio.DomInterop\ClientLib` +1. **Get `NPM` ready to run**: `npm install` +1. **Build the assets**: `npm run build` +1. **Navigate to ClientLib folder in Elsa.Studio.Workflows.Designer**: `cd .\src\modules\Elsa.Studio.Workflows.Designer\ClientLib` +1. **Get `NPM` ready to run**: `npm install` +1. **Build the assets**: `npm run build` + +## Build and Run + +1. **Restore .NET dependencies**: `dotnet restore Elsa.Studio.sln` +1. **Build the project**: `dotnet build Elsa.Studio.sln` +1. **For Blazor Server Host**: `dotnet run --project .\src\hosts\Elsa.Studio.Host.Server\Elsa.Studio.Host.Server.csproj ` +1. **For Blazor Server WASM**: `dotnet run --project .\src\hosts\Elsa.Studio.Host.Wasm\Elsa.Studio.Host.Wasm.csproj` + +Explore the [Elsa Studio GitHub repository](https://github.com/elsa-workflows/elsa-studio) for more detailed information. + +## Localization + +Elsa Studio is translated using [Weblate](https://hosted.weblate.org/engage/elsa-studio/) + + +Translation status + diff --git a/artwork/screenshot-1.png b/artwork/screenshot-1.png new file mode 100644 index 0000000..854f730 Binary files /dev/null and b/artwork/screenshot-1.png differ diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..47e1cad Binary files /dev/null and b/icon.png differ diff --git a/samples/BlazorApp1/BlazorApp1.csproj b/samples/BlazorApp1/BlazorApp1.csproj new file mode 100644 index 0000000..c815dfa --- /dev/null +++ b/samples/BlazorApp1/BlazorApp1.csproj @@ -0,0 +1,11 @@ + + + + net8.0 + + + + + + + diff --git a/samples/BlazorApp1/Components/App.razor b/samples/BlazorApp1/Components/App.razor new file mode 100644 index 0000000..d92228e --- /dev/null +++ b/samples/BlazorApp1/Components/App.razor @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/BlazorApp1/Components/Layout/MainLayout.razor b/samples/BlazorApp1/Components/Layout/MainLayout.razor new file mode 100644 index 0000000..ebc70e0 --- /dev/null +++ b/samples/BlazorApp1/Components/Layout/MainLayout.razor @@ -0,0 +1,15 @@ +@inherits LayoutComponentBase + + + + +@Body + +
+ An unhandled error has occurred. + Reload + 🗙 +
\ No newline at end of file diff --git a/samples/BlazorApp1/Components/Layout/MainLayout.razor.css b/samples/BlazorApp1/Components/Layout/MainLayout.razor.css new file mode 100644 index 0000000..038baf1 --- /dev/null +++ b/samples/BlazorApp1/Components/Layout/MainLayout.razor.css @@ -0,0 +1,96 @@ +.page { + position: relative; + display: flex; + flex-direction: column; +} + +main { + flex: 1; +} + +.sidebar { + background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); +} + +.top-row { + background-color: #f7f7f7; + border-bottom: 1px solid #d6d5d5; + justify-content: flex-end; + height: 3.5rem; + display: flex; + align-items: center; +} + + .top-row ::deep a, .top-row ::deep .btn-link { + white-space: nowrap; + margin-left: 1.5rem; + text-decoration: none; + } + + .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { + text-decoration: underline; + } + + .top-row ::deep a:first-child { + overflow: hidden; + text-overflow: ellipsis; + } + +@media (max-width: 640.98px) { + .top-row { + justify-content: space-between; + } + + .top-row ::deep a, .top-row ::deep .btn-link { + margin-left: 0; + } +} + +@media (min-width: 641px) { + .page { + flex-direction: row; + } + + .sidebar { + width: 250px; + height: 100vh; + position: sticky; + top: 0; + } + + .top-row { + position: sticky; + top: 0; + z-index: 1; + } + + .top-row.auth ::deep a:first-child { + flex: 1; + text-align: right; + width: 0; + } + + .top-row, article { + padding-left: 2rem !important; + padding-right: 1.5rem !important; + } +} + +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + + #blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; + } diff --git a/samples/BlazorApp1/Components/Pages/Counter.razor b/samples/BlazorApp1/Components/Pages/Counter.razor new file mode 100644 index 0000000..b72f6bf --- /dev/null +++ b/samples/BlazorApp1/Components/Pages/Counter.razor @@ -0,0 +1,20 @@ +@page "/" +@rendermode InteractiveServer + +Counter + +

Counter

+ +

Current count: @currentCount

+ + + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } + +} \ No newline at end of file diff --git a/samples/BlazorApp1/Components/Pages/Error.razor b/samples/BlazorApp1/Components/Pages/Error.razor new file mode 100644 index 0000000..9d7c6be --- /dev/null +++ b/samples/BlazorApp1/Components/Pages/Error.razor @@ -0,0 +1,36 @@ +@page "/Error" +@using System.Diagnostics + +Error + +

Error.

+

An error occurred while processing your request.

+ +@if (ShowRequestId) +{ +

+ Request ID: @RequestId +

+} + +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

+ +@code{ + [CascadingParameter] private HttpContext? HttpContext { get; set; } + + private string? RequestId { get; set; } + private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + protected override void OnInitialized() => + RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; + +} \ No newline at end of file diff --git a/samples/BlazorApp1/Components/Pages/Weather.razor b/samples/BlazorApp1/Components/Pages/Weather.razor new file mode 100644 index 0000000..f31f2ee --- /dev/null +++ b/samples/BlazorApp1/Components/Pages/Weather.razor @@ -0,0 +1,67 @@ +@page "/weather" +@attribute [StreamRendering] + +Weather + +

Weather

+ +

This component demonstrates showing data.

+ +@if (forecasts == null) +{ +

+ Loading... +

+} +else +{ + + + + + + + + + + + @foreach (var forecast in forecasts) + { + + + + + + + } + +
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
+} + +@code { + private WeatherForecast[]? forecasts; + + protected override async Task OnInitializedAsync() + { + // Simulate asynchronous loading to demonstrate streaming rendering + await Task.Delay(500); + + var startDate = DateOnly.FromDateTime(DateTime.Now); + var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; + forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = startDate.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = summaries[Random.Shared.Next(summaries.Length)] + }).ToArray(); + } + + private class WeatherForecast + { + public DateOnly Date { get; set; } + public int TemperatureC { get; set; } + public string? Summary { get; set; } + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + } + +} \ No newline at end of file diff --git a/samples/BlazorApp1/Components/Pages/WorkflowDefinitionEditor.razor b/samples/BlazorApp1/Components/Pages/WorkflowDefinitionEditor.razor new file mode 100644 index 0000000..dc10b99 --- /dev/null +++ b/samples/BlazorApp1/Components/Pages/WorkflowDefinitionEditor.razor @@ -0,0 +1,28 @@ +@page "/workflow-definitions/{definitionId}" +@using Elsa.Api.Client.Resources.WorkflowDefinitions.Models +@rendermode InteractiveServer + + +Get Current Version + +@code +{ + /// + /// The ID of the workflow definition to edit. + /// + [Parameter] + public string DefinitionId { get; set; } = default!; + + private WorkflowDefinitionEditorWrapper Editor { get; set; } = default!; + + private Task WorkflowDefinitionVersionSelected(WorkflowDefinition arg) + { + return Task.CompletedTask; + } + + private Task OnClick() + { + var selectedVersion = Editor.GetSelectedWorkflowDefinitionVersion(); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/samples/BlazorApp1/Components/Pages/WorkflowDefinitions.razor b/samples/BlazorApp1/Components/Pages/WorkflowDefinitions.razor new file mode 100644 index 0000000..258542e --- /dev/null +++ b/samples/BlazorApp1/Components/Pages/WorkflowDefinitions.razor @@ -0,0 +1,12 @@ +@page "/workflow-definitions" +@rendermode InteractiveServer + + +@code { + [Inject] NavigationManager NavigationManager { get; set; } = default!; + + private void OnEditWorkflowDefinition(string definitionId) + { + NavigationManager.NavigateTo($"workflow-definitions/{definitionId}"); + } +} \ No newline at end of file diff --git a/samples/BlazorApp1/Components/Pages/WorkflowInstanceViewer.razor b/samples/BlazorApp1/Components/Pages/WorkflowInstanceViewer.razor new file mode 100644 index 0000000..f74c041 --- /dev/null +++ b/samples/BlazorApp1/Components/Pages/WorkflowInstanceViewer.razor @@ -0,0 +1,12 @@ +@page "/workflow-instances/{instanceId}" +@rendermode InteractiveServer + + +@code +{ + /// + /// The ID of the workflow instance to edit. + /// + [Parameter] + public string InstanceId { get; set; } = default!; +} \ No newline at end of file diff --git a/samples/BlazorApp1/Components/Pages/WorkflowInstances.razor b/samples/BlazorApp1/Components/Pages/WorkflowInstances.razor new file mode 100644 index 0000000..587e923 --- /dev/null +++ b/samples/BlazorApp1/Components/Pages/WorkflowInstances.razor @@ -0,0 +1,15 @@ +@page "/workflow-instances" + +@rendermode InteractiveServer + + +@code { + + [Inject] NavigationManager NavigationManager { get; set; } = default!; + + private void OnViewWorkflowInstance(string instanceId) + { + NavigationManager.NavigateTo($"workflow-instances/{instanceId}"); + } + +} \ No newline at end of file diff --git a/samples/BlazorApp1/Components/Routes.razor b/samples/BlazorApp1/Components/Routes.razor new file mode 100644 index 0000000..bf0ce0b --- /dev/null +++ b/samples/BlazorApp1/Components/Routes.razor @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/samples/BlazorApp1/Components/_Imports.razor b/samples/BlazorApp1/Components/_Imports.razor new file mode 100644 index 0000000..4ac6dfa --- /dev/null +++ b/samples/BlazorApp1/Components/_Imports.razor @@ -0,0 +1,12 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using BlazorApp1 +@using BlazorApp1.Components +@using Elsa.Studio.Host.CustomElements.Components +@using MudBlazor \ No newline at end of file diff --git a/samples/BlazorApp1/Program.cs b/samples/BlazorApp1/Program.cs new file mode 100644 index 0000000..d5505d7 --- /dev/null +++ b/samples/BlazorApp1/Program.cs @@ -0,0 +1,58 @@ +using BlazorApp1.Components; +using Elsa.Studio.Contracts; +using Elsa.Studio.Core.BlazorWasm.Extensions; +using Elsa.Studio.Extensions; +using Elsa.Studio.Host.CustomElements.HttpMessageHandlers; +using Elsa.Studio.Host.CustomElements.Services; +using Elsa.Studio.Models; +using Elsa.Studio.Shell.Extensions; +using Elsa.Studio.Workflows.Designer.Extensions; +using Elsa.Studio.Workflows.Extensions; +using Microsoft.Extensions.DependencyInjection.Extensions; + +var builder = WebApplication.CreateBuilder(args); +var configuration = builder.Configuration; + +// Add services to the container. +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(circuitOptions => circuitOptions.RootComponents.RegisterCustomElsaStudioElements()); + +// Register local services. +builder.Services.AddSingleton(); + +// Register the modules. +var backendApiConfig = new BackendApiConfig +{ + ConfigureBackendOptions = options => configuration.GetSection("Backend").Bind(options), + ConfigureHttpClientBuilder = options => + { + options.ApiKey = configuration["Backend:ApiKey"]; + options.AuthenticationHandler = typeof(AuthHttpMessageHandler); + } +}; + +builder.Services.AddCore(); +builder.Services.AddShell(); +builder.Services.AddRemoteBackend(backendApiConfig); +builder.Services.Replace(ServiceDescriptor.Scoped()); +builder.Services.AddWorkflowsModule(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error", createScopeForErrors: true); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); + +app.UseStaticFiles(); +app.UseAntiforgery(); + +app.MapRazorComponents() + .AddInteractiveServerRenderMode(); + +app.Run(); \ No newline at end of file diff --git a/samples/BlazorApp1/Properties/launchSettings.json b/samples/BlazorApp1/Properties/launchSettings.json new file mode 100644 index 0000000..d331b3d --- /dev/null +++ b/samples/BlazorApp1/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:22097", + "sslPort": 44321 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5046", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7231;http://localhost:5046", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } + } diff --git a/samples/BlazorApp1/appsettings.Development.json b/samples/BlazorApp1/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/samples/BlazorApp1/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/samples/BlazorApp1/appsettings.json b/samples/BlazorApp1/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/samples/BlazorApp1/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/samples/BlazorApp1/wwwroot/favicon.png b/samples/BlazorApp1/wwwroot/favicon.png new file mode 100644 index 0000000..8422b59 Binary files /dev/null and b/samples/BlazorApp1/wwwroot/favicon.png differ diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/.gitignore b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/.gitignore new file mode 100644 index 0000000..4d29575 --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/.npmrc b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/.npmrc new file mode 100644 index 0000000..e559d66 --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/.npmrc @@ -0,0 +1 @@ +registry=https://f.feedz.io/elsa-workflows/elsa-3/npm/ \ No newline at end of file diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/README.md b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/README.md new file mode 100644 index 0000000..58beeac --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/README.md @@ -0,0 +1,70 @@ +# Getting Started with Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Available Scripts + +In the project directory, you can run: + +### `npm start` + +Runs the app in the development mode.\ +Open [http://localhost:3000](http://localhost:3000) to view it in your browser. + +The page will reload when you make changes.\ +You may also see any lint errors in the console. + +### `npm test` + +Launches the test runner in the interactive watch mode.\ +See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. + +### `npm run build` + +Builds the app for production to the `build` folder.\ +It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.\ +Your app is ready to be deployed! + +See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. + +### `npm run eject` + +**Note: this is a one-way operation. Once you `eject`, you can't go back!** + +If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. + +You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) + +### Analyzing the Bundle Size + +This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) + +### Making a Progressive Web App + +This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) + +### Advanced Configuration + +This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) + +### Deployment + +This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) + +### `npm run build` fails to minify + +This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/package-lock.json b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/package-lock.json new file mode 100644 index 0000000..7a4e2e5 --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/package-lock.json @@ -0,0 +1,29962 @@ +{ + "name": "workflow-definition-editor-app", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "workflow-definition-editor-app", + "version": "0.1.0", + "hasInstallScript": true, + "dependencies": { + "@elsa-workflows/elsa-studio-wasm": "^3.0.0-preview.1", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-scripts": "5.0.1", + "uuid": "^9.0.0", + "web-vitals": "^2.1.4" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.2.0.tgz", + "integrity": "sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==" + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dependencies": { + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", + "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.9", + "@babel/helper-module-transforms": "^7.22.9", + "@babel/helpers": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.8", + "@babel/types": "^7.22.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.9.tgz", + "integrity": "sha512-xdMkt39/nviO/4vpVdrEYPwXCsYIXSSAr6mC7WQsNIlGnuxKyKE7GZjalcnbSWiC4OXGNNN3UQPeHfjSC6sTDA==", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz", + "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==", + "dependencies": { + "@babel/types": "^7.22.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", + "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz", + "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==", + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz", + "integrity": "sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz", + "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", + "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", + "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", + "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz", + "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-wrap-function": "^7.22.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", + "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz", + "integrity": "sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", + "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", + "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.22.7.tgz", + "integrity": "sha512-omXqPF7Onq4Bb7wHxXjM3jSMSJvUUbvDvmmds7KI5n9Cq6Ln5I05I1W2nRlRof1rGdiUxJrxwe285WF96XlBXQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/plugin-syntax-decorators": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.5.tgz", + "integrity": "sha512-avpUOBS7IU6al8MmF1XpAyj9QYeLPuSDJI5D4pVMSMdL7xQokKqJPYQC67RCT0aCTashUXPiGwMJ0DEXXCEmMA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz", + "integrity": "sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz", + "integrity": "sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", + "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", + "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", + "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", + "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", + "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", + "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz", + "integrity": "sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", + "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", + "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", + "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", + "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", + "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", + "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", + "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", + "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", + "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "dependencies": { + "@babel/compat-data": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", + "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz", + "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", + "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", + "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.22.5.tgz", + "integrity": "sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", + "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", + "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", + "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", + "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz", + "integrity": "sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.4", + "babel-plugin-polyfill-corejs3": "^0.8.2", + "babel-plugin-polyfill-regenerator": "^0.5.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz", + "integrity": "sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.9", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", + "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz", + "integrity": "sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==", + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.9", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.7", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.5", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.5", + "@babel/plugin-transform-classes": "^7.22.6", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.5", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.5", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.5", + "@babel/plugin-transform-for-of": "^7.22.5", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.5", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/plugin-transform-modules-systemjs": "^7.22.5", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", + "@babel/plugin-transform-numeric-separator": "^7.22.5", + "@babel/plugin-transform-object-rest-spread": "^7.22.5", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.6", + "@babel/plugin-transform-parameters": "^7.22.5", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.5", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.5", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.5", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.4", + "babel-plugin-polyfill-corejs3": "^0.8.2", + "babel-plugin-polyfill-regenerator": "^0.5.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz", + "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz", + "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-transform-react-display-name": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.5", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz", + "integrity": "sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/plugin-transform-typescript": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "node_modules/@babel/runtime": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", + "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "dependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/types": "^7.22.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "node_modules/@csstools/normalize.css": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", + "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==" + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@elsa-workflows/elsa-studio-wasm": { + "version": "3.0.0-preview.1", + "resolved": "https://f.feedz.io/elsa-workflows/elsa-3/npm/%40elsa-workflows%2felsa-studio-wasm/3.0.0-preview.1/download", + "integrity": "sha512-18Bxv9FBaGoUZHsmvFV9VN8wGvt8b2VO5dlXdNk5D6akNYdwypwkNakrgOhmr8+1TNnv2hc3sHTgaHyfaMex4A==" + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.1.tgz", + "integrity": "sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==", + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", + "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", + "dependencies": { + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.4", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <4.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz", + "integrity": "sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "dependencies": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "dependencies": { + "@babel/types": "^7.12.6" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "dependencies": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "dependencies": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@testing-library/dom": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", + "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "peer": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/dom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "peer": true + }, + "node_modules/@testing-library/dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "dependencies": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@testing-library/jest-dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", + "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.5.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/react/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/react/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/react/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@testing-library/react/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", + "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.1.tgz", + "integrity": "sha512-XpNDc4Z5Tb4x+SW1MriMVeIsMoONHCkWFMkR/aPJbzEsxqHy+4Glu/BqTdPrApfDeMaXbtNh6bseNgl5KaWrSg==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", + "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.3.tgz", + "integrity": "sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jest/node_modules/@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/@jest/types": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", + "dependencies": { + "@jest/schemas": "^29.6.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@types/jest/node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@types/jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@types/jest/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/expect": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==", + "dependencies": { + "@jest/expect-utils": "^29.6.1", + "@types/node": "*", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@types/jest/node_modules/jest-diff": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.1.tgz", + "integrity": "sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/jest-matcher-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz", + "integrity": "sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.6.1", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/jest-message-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.1.tgz", + "integrity": "sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/jest-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.1.tgz", + "integrity": "sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==", + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@types/jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "node_modules/@types/node": { + "version": "20.4.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", + "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==" + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "node_modules/@types/q": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/react": { + "version": "18.2.16", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.16.tgz", + "integrity": "sha512-LLFWr12ZhBJ4YVw7neWLe6Pk7Ey5R9OCydfuMsz1L8bZxzaawJj2p06Q8/EFEHDeTBQNFLF62X+CG7B2zIyu0Q==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", + "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/scheduler": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + }, + "node_modules/@types/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==" + }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" + }, + "node_modules/@types/ws": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", + "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", + "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", + "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", + "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-loader": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "peerDependencies": { + "@babel/core": "^7.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", + "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz", + "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2", + "core-js-compat": "^3.31.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", + "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-react-app": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/bfj": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", + "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "dependencies": { + "bluebird": "^3.5.5", + "check-types": "^11.1.1", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "node_modules/browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001517", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", + "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/check-types": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz", + "integrity": "sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==" + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" + }, + "node_modules/clean-css": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", + "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-js": { + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.1.tgz", + "integrity": "sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.1.tgz", + "integrity": "sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==", + "dependencies": { + "browserslist": "^4.21.9" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.31.1.tgz", + "integrity": "sha512-w+C62kvWti0EPs4KPMCMVv9DriHSXfQOCQ94bGGBiEW5rrbtt/Rz8n5Krhfw9cpFyzXBjf3DB3QnPdEzGDY4Fw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-blank-pseudo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-blank-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-has-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "dependencies": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "bin": { + "css-prefers-color-scheme": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" + }, + "node_modules/cssdb": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.7.0.tgz", + "integrity": "sha512-1hN+I3r4VqSNQ+OmMXxYexnumbOONkSil0TWMebVXHtzYW4tRRPovUNHPHj2d4nrgOuYJ8Vs3XwvywsuwwXNNA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ] + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "dependencies": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" + }, + "node_modules/deep-equal": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz", + "integrity": "sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.1", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + }, + "node_modules/dns-packet": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", + "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.471", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.471.tgz", + "integrity": "sha512-GpmGRC1vTl60w/k6YpQ18pSiqnmr0j3un//5TV1idPi6aheNfkT1Ye71tMEabWyNDO6sBMgAR+95Eb0eUUr1tA==" + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-module-lexer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==" + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", + "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.6.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "dependencies": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", + "has": "^1.0.3", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", + "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", + "dependencies": { + "@babel/runtime": "^7.20.7", + "aria-query": "^5.1.3", + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.6.2", + "axobject-query": "^3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.3", + "language-tags": "=1.0.5", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.0.tgz", + "integrity": "sha512-qewL/8P34WkY8jAqdQxsiL82pDUeT7nhs8IsuXgfgnsEloKCT4miAV9N9kGtx7/KM9NH/NCGUE7Edt9iGxLXFw==", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-testing-library": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.0.tgz", + "integrity": "sha512-ELY7Gefo+61OfXKlQeXNIDVVLPcvKTeiQOoMZG9TeuWa7Ln4dUNRv8JdRWBQI9Mbb427XGlVB1aa1QPZxBJM8Q==", + "dependencies": { + "@typescript-eslint/utils": "^5.58.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6" + }, + "peerDependencies": { + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz", + "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "dependencies": { + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0", + "webpack": "^5.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", + "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "engines": { + "node": ">=6" + } + }, + "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==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-jasmine2/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-jasmine2/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", + "dependencies": { + "ansi-escapes": "^4.3.1", + "chalk": "^4.0.0", + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "jest": "^27.0.0 || ^28.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-watch-typeahead/node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-watch-typeahead/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", + "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.4.tgz", + "integrity": "sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw==", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" + }, + "node_modules/language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "dependencies": { + "language-subtag-registry": "~0.3.2" + } + }, + "node_modules/launch-editor": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", + "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.7.3" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", + "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", + "dependencies": { + "array.prototype.reduce": "^1.0.5", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.21.2", + "safe-array-concat": "^1.0.0" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", + "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "browserslist": ">=4", + "postcss": ">=8" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-custom-media": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-custom-properties": { + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "peerDependencies": { + "postcss": "^8.1.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + }, + "engines": { + "node": ">= 14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "dependencies": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-media-minmax": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nesting": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-normalize": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", + "dependencies": { + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "browserslist": ">= 4", + "postcss": ">= 8" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-preset-env": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "dependencies": { + "@csstools/postcss-cascade-layers": "^1.1.1", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.1.0", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.10", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/postcss-svgo/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/postcss-svgo/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-app-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "dependencies": { + "core-js": "^3.19.2", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/react-dev-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/react-dev-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/react-dev-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/react-dev-utils/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "dependencies": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "bin": { + "react-scripts": "bin/react-scripts.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + }, + "peerDependencies": { + "react": ">= 16", + "typescript": "^3.2.1 || ^4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=8.9" + }, + "peerDependencies": { + "rework": "1.0.1", + "rework-visit": "1.0.0" + }, + "peerDependenciesMeta": { + "rework": { + "optional": true + }, + "rework-visit": { + "optional": true + } + } + }, + "node_modules/resolve-url-loader/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "node_modules/resolve-url-loader/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-terser/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", + "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sanitize.css": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" + }, + "node_modules/sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/selfsigned": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "dependencies": { + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", + "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", + "dependencies": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz", + "integrity": "sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==", + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/sucrase": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", + "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/tailwindcss": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", + "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.18.2", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.19.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", + "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throat": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "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==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-vitals": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", + "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "engines": { + "node": ">=10.4" + } + }, + "node_modules/webpack": { + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", + "dependencies": { + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "peerDependencies": { + "webpack": "^4.44.2 || ^5.47.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "dependencies": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.17", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz", + "integrity": "sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ==" + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/workbox-build/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/workbox-build/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" + }, + "node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "dependencies": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "dependencies": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" + }, + "node_modules/workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "dependencies": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/workbox-window": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.6.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==" + }, + "@adobe/css-tools": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.2.0.tgz", + "integrity": "sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==" + }, + "@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==" + }, + "@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "requires": { + "@babel/highlight": "^7.22.5" + } + }, + "@babel/compat-data": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==" + }, + "@babel/core": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", + "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.9", + "@babel/helper-module-transforms": "^7.22.9", + "@babel/helpers": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.8", + "@babel/types": "^7.22.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/eslint-parser": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.9.tgz", + "integrity": "sha512-xdMkt39/nviO/4vpVdrEYPwXCsYIXSSAr6mC7WQsNIlGnuxKyKE7GZjalcnbSWiC4OXGNNN3UQPeHfjSC6sTDA==", + "requires": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/generator": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz", + "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==", + "requires": { + "@babel/types": "^7.22.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", + "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz", + "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==", + "requires": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz", + "integrity": "sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz", + "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", + "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", + "requires": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==" + }, + "@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "requires": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", + "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", + "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.5" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==" + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz", + "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-wrap-function": "^7.22.9" + } + }, + "@babel/helper-replace-supers": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", + "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", + "requires": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" + }, + "@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" + }, + "@babel/helper-validator-option": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==" + }, + "@babel/helper-wrap-function": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz", + "integrity": "sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==", + "requires": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/helpers": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", + "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "requires": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.6", + "@babel/types": "^7.22.5" + } + }, + "@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==" + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", + "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", + "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.5" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-decorators": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.22.7.tgz", + "integrity": "sha512-omXqPF7Onq4Bb7wHxXjM3jSMSJvUUbvDvmmds7KI5n9Cq6Ln5I05I1W2nRlRof1rGdiUxJrxwe285WF96XlBXQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/plugin-syntax-decorators": "^7.22.5" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "requires": {} + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.5.tgz", + "integrity": "sha512-avpUOBS7IU6al8MmF1XpAyj9QYeLPuSDJI5D4pVMSMdL7xQokKqJPYQC67RCT0aCTashUXPiGwMJ0DEXXCEmMA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz", + "integrity": "sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-async-generator-functions": { + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz", + "integrity": "sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==", + "requires": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "requires": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", + "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-static-block": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", + "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", + "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", + "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dynamic-import": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", + "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-export-namespace-from": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", + "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz", + "integrity": "sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.22.5" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", + "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "requires": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-json-strings": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", + "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", + "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", + "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", + "requires": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", + "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "requires": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", + "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", + "requires": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", + "requires": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", + "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-transform-numeric-separator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", + "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-transform-object-rest-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", + "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "requires": { + "@babel/compat-data": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.5" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + } + }, + "@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", + "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-transform-optional-chaining": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz", + "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", + "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", + "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-react-constant-elements": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.22.5.tgz", + "integrity": "sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", + "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", + "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "requires": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + } + }, + "@babel/plugin-transform-react-pure-annotations": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", + "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", + "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.1" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz", + "integrity": "sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ==", + "requires": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.4", + "babel-plugin-polyfill-corejs3": "^0.8.2", + "babel-plugin-polyfill-regenerator": "^0.5.1", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz", + "integrity": "sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.9", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", + "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/preset-env": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz", + "integrity": "sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==", + "requires": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.9", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.7", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.5", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.5", + "@babel/plugin-transform-classes": "^7.22.6", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.5", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.5", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.5", + "@babel/plugin-transform-for-of": "^7.22.5", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.5", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/plugin-transform-modules-systemjs": "^7.22.5", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", + "@babel/plugin-transform-numeric-separator": "^7.22.5", + "@babel/plugin-transform-object-rest-spread": "^7.22.5", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.6", + "@babel/plugin-transform-parameters": "^7.22.5", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.5", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.5", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.5", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.4", + "babel-plugin-polyfill-corejs3": "^0.8.2", + "babel-plugin-polyfill-regenerator": "^0.5.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/preset-modules": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz", + "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-react": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz", + "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-transform-react-display-name": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.5", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.22.5" + } + }, + "@babel/preset-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz", + "integrity": "sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/plugin-transform-typescript": "^7.22.5" + } + }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "@babel/runtime": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "requires": { + "regenerator-runtime": "^0.13.11" + } + }, + "@babel/template": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "requires": { + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" + } + }, + "@babel/traverse": { + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", + "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "requires": { + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.7", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.7", + "@babel/types": "^7.22.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "requires": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "@csstools/normalize.css": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", + "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==" + }, + "@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", + "requires": { + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" + } + }, + "@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", + "requires": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + } + }, + "@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", + "requires": {} + }, + "@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "requires": {} + }, + "@elsa-workflows/elsa-studio-wasm": { + "version": "3.0.0-preview.1", + "resolved": "https://f.feedz.io/elsa-workflows/elsa-3/npm/%40elsa-workflows%2felsa-studio-wasm/3.0.0-preview.1/download", + "integrity": "sha512-18Bxv9FBaGoUZHsmvFV9VN8wGvt8b2VO5dlXdNk5D6akNYdwypwkNakrgOhmr8+1TNnv2hc3sHTgaHyfaMex4A==" + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==" + }, + "@eslint/eslintrc": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "requires": { + "type-fest": "^0.20.2" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + } + } + }, + "@eslint/js": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==" + }, + "@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" + }, + "@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "requires": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "requires": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + } + }, + "@jest/expect-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.1.tgz", + "integrity": "sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==", + "requires": { + "jest-get-type": "^29.4.3" + }, + "dependencies": { + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==" + } + } + }, + "@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "requires": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + } + }, + "@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + } + }, + "@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "requires": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "requires": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + } + }, + "@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + } + } + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "requires": { + "eslint-scope": "5.1.1" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", + "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", + "requires": { + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.4", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" + } + }, + "@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + } + }, + "@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "requires": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + } + } + }, + "@rushstack/eslint-patch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz", + "integrity": "sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==" + }, + "@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + }, + "@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "requires": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==" + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==" + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==" + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==" + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==" + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==" + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==" + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==" + }, + "@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "requires": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + } + }, + "@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "requires": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + } + }, + "@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "requires": { + "@babel/types": "^7.12.6" + } + }, + "@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "requires": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + } + }, + "@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "requires": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + } + }, + "@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "requires": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + } + }, + "@testing-library/dom": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", + "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", + "peer": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "peer": true, + "requires": { + "deep-equal": "^2.0.5" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "peer": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@testing-library/jest-dom": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "requires": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@testing-library/react": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", + "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "requires": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.5.0", + "@types/react-dom": "^18.0.0" + }, + "dependencies": { + "@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "requires": { + "deep-equal": "^2.0.5" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "requires": { + "@babel/runtime": "^7.12.5" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" + }, + "@types/aria-query": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", + "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==" + }, + "@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "requires": { + "@babel/types": "^7.20.7" + } + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/eslint": { + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.1.tgz", + "integrity": "sha512-XpNDc4Z5Tb4x+SW1MriMVeIsMoONHCkWFMkR/aPJbzEsxqHy+4Glu/BqTdPrApfDeMaXbtNh6bseNgl5KaWrSg==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + }, + "@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "requires": { + "@types/node": "*" + } + }, + "@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==" + }, + "@types/http-proxy": { + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", + "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "29.5.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.3.tgz", + "integrity": "sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==", + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", + "requires": { + "@jest/schemas": "^29.6.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==" + }, + "expect": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==", + "requires": { + "@jest/expect-utils": "^29.6.1", + "@types/node": "*", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "jest-diff": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.1.tgz", + "integrity": "sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==", + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + } + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==" + }, + "jest-matcher-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz", + "integrity": "sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==", + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.6.1", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + } + }, + "jest-message-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.1.tgz", + "integrity": "sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.1.tgz", + "integrity": "sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==", + "requires": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "requires": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + } + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==" + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "@types/node": { + "version": "20.4.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", + "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==" + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" + }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "@types/q": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "@types/react": { + "version": "18.2.16", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.16.tgz", + "integrity": "sha512-LLFWr12ZhBJ4YVw7neWLe6Pk7Ey5R9OCydfuMsz1L8bZxzaawJj2p06Q8/EFEHDeTBQNFLF62X+CG7B2zIyu0Q==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.2.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", + "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", + "requires": { + "@types/react": "*" + } + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "requires": { + "@types/node": "*" + } + }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "@types/scheduler": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + }, + "@types/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==" + }, + "@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "requires": { + "@types/node": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" + }, + "@types/testing-library__jest-dom": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "requires": { + "@types/jest": "*" + } + }, + "@types/trusted-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" + }, + "@types/ws": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "requires": { + "@types/node": "*" + } + }, + "@types/yargs": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", + "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "requires": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "requires": { + "@typescript-eslint/utils": "5.62.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "requires": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "requires": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "requires": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==" + }, + "@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "requires": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "requires": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } + }, + "acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "requires": {} + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "requires": {} + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + }, + "address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==" + }, + "adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "requires": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + } + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "requires": { + "dequal": "^2.0.3" + } + }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + }, + "array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.reduce": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", + "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + } + }, + "array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", + "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", + "requires": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" + }, + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "requires": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" + }, + "axe-core": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", + "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==" + }, + "axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "requires": { + "dequal": "^2.0.3" + } + }, + "babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "requires": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "babel-loader": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "requires": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, + "babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "requires": {} + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", + "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", + "requires": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.2", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz", + "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.4.2", + "core-js-compat": "^3.31.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", + "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.4.2" + } + }, + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "requires": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "babel-preset-react-app": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "requires": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "bfj": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", + "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "requires": { + "bluebird": "^3.5.5", + "check-types": "^11.1.1", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "requires": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001517", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", + "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==" + }, + "case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" + }, + "check-types": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz", + "integrity": "sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==" + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==" + }, + "cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" + }, + "clean-css": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", + "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==" + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + }, + "connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "core-js": { + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.1.tgz", + "integrity": "sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ==" + }, + "core-js-compat": { + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.1.tgz", + "integrity": "sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==", + "requires": { + "browserslist": "^4.21.9" + } + }, + "core-js-pure": { + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.31.1.tgz", + "integrity": "sha512-w+C62kvWti0EPs4KPMCMVv9DriHSXfQOCQ94bGGBiEW5rrbtt/Rz8n5Krhfw9cpFyzXBjf3DB3QnPdEzGDY4Fw==" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, + "css-blank-pseudo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "requires": { + "postcss-selector-parser": "^6.0.9" + } + }, + "css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "requires": {} + }, + "css-has-pseudo": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "requires": { + "postcss-selector-parser": "^6.0.9" + } + }, + "css-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + } + }, + "css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "requires": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "requires": {} + }, + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" + }, + "cssdb": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.7.0.tgz", + "integrity": "sha512-1hN+I3r4VqSNQ+OmMXxYexnumbOONkSil0TWMebVXHtzYW4tRRPovUNHPHj2d4nrgOuYJ8Vs3XwvywsuwwXNNA==" + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "requires": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + } + }, + "cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "requires": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + } + }, + "cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "requires": {} + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "requires": { + "css-tree": "^1.1.2" + }, + "dependencies": { + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" + }, + "deep-equal": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz", + "integrity": "sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==", + "requires": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.1", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" + }, + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "requires": { + "execa": "^5.0.0" + } + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" + }, + "define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + }, + "dns-packet": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", + "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "requires": { + "utila": "~0.4" + } + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } + } + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, + "dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "requires": { + "jake": "^10.8.5" + } + }, + "electron-to-chromium": { + "version": "1.4.471", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.471.tgz", + "integrity": "sha512-GpmGRC1vTl60w/k6YpQ18pSiqnmr0j3un//5TV1idPi6aheNfkT1Ye71tMEabWyNDO6sBMgAR+95Eb0eUUr1tA==" + }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==" + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "requires": { + "stackframe": "^1.3.4" + } + }, + "es-abstract": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "requires": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + } + }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + } + }, + "es-module-lexer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==" + }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } + } + }, + "eslint": { + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", + "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.6.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + } + } + }, + "eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "requires": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "requires": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + } + }, + "eslint-plugin-import": { + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", + "has": "^1.0.3", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "requires": { + "@typescript-eslint/experimental-utils": "^5.0.0" + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", + "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", + "requires": { + "@babel/runtime": "^7.20.7", + "aria-query": "^5.1.3", + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.6.2", + "axobject-query": "^3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.3", + "language-tags": "=1.0.5", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "eslint-plugin-react": { + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.0.tgz", + "integrity": "sha512-qewL/8P34WkY8jAqdQxsiL82pDUeT7nhs8IsuXgfgnsEloKCT4miAV9N9kGtx7/KM9NH/NCGUE7Edt9iGxLXFw==", + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "requires": {} + }, + "eslint-plugin-testing-library": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.0.tgz", + "integrity": "sha512-ELY7Gefo+61OfXKlQeXNIDVVLPcvKTeiQOoMZG9TeuWa7Ln4dUNRv8JdRWBQI9Mbb427XGlVB1aa1QPZxBJM8Q==", + "requires": { + "@typescript-eslint/utils": "^5.58.0" + } + }, + "eslint-scope": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz", + "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==" + }, + "eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "requires": { + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==" + }, + "expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "requires": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + } + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "requires": { + "bser": "2.1.1" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + } + }, + "filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "requires": { + "minimatch": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + } + } + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-monkey": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", + "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "requires": { + "is-glob": "^4.0.3" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "requires": { + "define-properties": "^1.1.3" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "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==" + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "requires": { + "duplexer": "^0.1.2" + } + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==" + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==" + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "requires": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + } + }, + "html-webpack-plugin": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "requires": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + } + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "requires": {} + }, + "idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, + "identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "requires": { + "harmony-reflect": "^1.4.6" + } + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==" + }, + "immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + } + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "requires": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==" + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" + }, + "is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==" + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" + }, + "is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" + }, + "is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==" + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "requires": { + "which-typed-array": "^1.1.11" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==" + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==" + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "requires": { + "semver": "^7.5.3" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "requires": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "requires": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + } + }, + "jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "requires": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "requires": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "requires": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "requires": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + } + }, + "jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + } + }, + "jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==" + }, + "jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "requires": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "requires": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "requires": {} + }, + "jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==" + }, + "jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "requires": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "requires": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + } + }, + "jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "requires": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + } + }, + "jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "requires": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-watch-typeahead": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", + "requires": { + "ansi-escapes": "^4.3.1", + "chalk": "^4.0.0", + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + } + } + }, + "@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "requires": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "requires": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + } + } + }, + "jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==" + }, + "jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "requires": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "dependencies": { + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + } + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" + }, + "string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "requires": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==" + } + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "requires": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jiti": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", + "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" + }, + "jsx-ast-utils": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.4.tgz", + "integrity": "sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw==", + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==" + }, + "language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, + "launch-editor": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", + "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.7.3" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==" + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" + }, + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==" + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "requires": { + "tmpl": "1.0.5" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "requires": { + "fs-monkey": "^1.0.4" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" + }, + "mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "requires": { + "schema-utils": "^4.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", + "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", + "requires": { + "array.prototype.reduce": "^1.0.5", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.21.2", + "safe-array-concat": "^1.0.0" + } + }, + "object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "requires": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + } + } + }, + "postcss": { + "version": "8.4.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", + "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "requires": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "requires": {} + }, + "postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "requires": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-color-rebeccapurple": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "requires": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "requires": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-custom-media": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-custom-properties": { + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-custom-selectors": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-dir-pseudo-class": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "requires": {} + }, + "postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "requires": {} + }, + "postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "requires": {} + }, + "postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "requires": {} + }, + "postcss-double-position-gradients": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "requires": {} + }, + "postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "requires": { + "postcss-selector-parser": "^6.0.9" + } + }, + "postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "requires": { + "postcss-selector-parser": "^6.0.9" + } + }, + "postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "requires": {} + }, + "postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "requires": {} + }, + "postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "requires": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "requires": {} + }, + "postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "requires": { + "camelcase-css": "^2.0.1" + } + }, + "postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + }, + "dependencies": { + "yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==" + } + } + }, + "postcss-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "requires": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + } + }, + "postcss-logical": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "requires": {} + }, + "postcss-media-minmax": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "requires": {} + }, + "postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "requires": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + } + }, + "postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "requires": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "requires": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "requires": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "requires": {} + }, + "postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "requires": { + "postcss-selector-parser": "^6.0.11" + } + }, + "postcss-nesting": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "requires": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-normalize": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", + "requires": { + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" + } + }, + "postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "requires": {} + }, + "postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "requires": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "requires": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-opacity-percentage": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", + "requires": {} + }, + "postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "requires": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-overflow-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "requires": {} + }, + "postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-preset-env": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "requires": { + "@csstools/postcss-cascade-layers": "^1.1.1", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.1.0", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.10", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-pseudo-class-any-link": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "requires": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "requires": {} + }, + "postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "requires": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + } + } + } + }, + "postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" + }, + "pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "requires": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "requires": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + } + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "requires": { + "asap": "~2.0.6" + } + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + } + } + }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "requires": { + "performance-now": "^2.1.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-app-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "requires": { + "core-js": "^3.19.2", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" + } + }, + "react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "requires": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + }, + "react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" + }, + "react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "requires": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "fsevents": "^2.3.2", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "requires": { + "pify": "^2.3.0" + } + }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "requires": { + "minimatch": "^3.0.5" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "regenerator-transform": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" + }, + "regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + } + }, + "regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "requires": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + } + }, + "regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" + } + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" + }, + "renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "requires": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "resolve-url-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "requires": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==" + }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-array-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", + "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sanitize.css": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" + }, + "sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "requires": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "selfsigned": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "requires": { + "node-forge": "^1" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + }, + "source-map-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", + "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", + "requires": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + } + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + }, + "stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + } + } + }, + "stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "requires": { + "internal-slot": "^1.0.4" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + } + } + }, + "string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "style-loader": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz", + "integrity": "sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==", + "requires": {} + }, + "stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "requires": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + } + }, + "sucrase": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", + "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "dependencies": { + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==" + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + } + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + } + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "tailwindcss": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", + "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", + "requires": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.18.2", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + }, + "temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==" + }, + "tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "requires": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "dependencies": { + "type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==" + } + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "terser": { + "version": "5.19.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", + "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, + "terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "requires": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "throat": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "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==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "dependencies": { + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" + } + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "requires": { + "punycode": "^2.1.1" + } + }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + }, + "ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + } + } + }, + "tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "peer": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" + }, + "unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + }, + "update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + }, + "v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "requires": { + "makeerror": "1.0.12" + } + }, + "watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "web-vitals": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", + "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + }, + "webpack": { + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + } + } + }, + "webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + } + } + }, + "webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "requires": {} + } + } + }, + "webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", + "requires": { + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + } + } + }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "whatwg-fetch": { + "version": "3.6.17", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz", + "integrity": "sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ==" + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "requires": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + } + }, + "which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, + "workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "requires": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "requires": { + "workbox-core": "6.6.0" + } + }, + "workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "requires": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "dependencies": { + "@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "requires": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + } + }, + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "requires": { + "whatwg-url": "^7.0.0" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "workbox-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "requires": { + "workbox-core": "6.6.0" + } + }, + "workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" + }, + "workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "requires": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "requires": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "requires": { + "workbox-core": "6.6.0" + } + }, + "workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "requires": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "requires": { + "workbox-core": "6.6.0" + } + }, + "workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "requires": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "requires": { + "workbox-core": "6.6.0" + } + }, + "workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "requires": { + "workbox-core": "6.6.0" + } + }, + "workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "requires": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" + }, + "workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "requires": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + } + } + }, + "workbox-window": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "requires": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.6.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + } + } +} diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/package.json b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/package.json new file mode 100644 index 0000000..0bfa776 --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/package.json @@ -0,0 +1,42 @@ +{ + "name": "workflow-definition-editor-app", + "version": "0.1.0", + "private": true, + "dependencies": { + "@elsa-workflows/elsa-studio-wasm": "^3.0.0-preview.1", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-scripts": "5.0.1", + "web-vitals": "^2.1.4", + "uuid": "^9.0.0" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject", + "postinstall": "npm run copy:elsa-studio-wasm", + "copy:elsa-studio-wasm": "cp -r node_modules/@elsa-workflows/elsa-studio-wasm/_content public/ && cp -r node_modules/@elsa-workflows/elsa-studio-wasm/_framework public/ && cp -r node_modules/@elsa-workflows/elsa-studio-wasm/appsettings.json public/" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/App.js b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/App.js new file mode 100644 index 0000000..dfd33e3 --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/App.js @@ -0,0 +1,12 @@ +import WorkflowDefinitionEditor from "./components/WorkflowDefinitionEditor"; + +function App() { + return ( +
+ + {/**/} +
+ ); +} + +export default App; diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/App.test.js b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/App.test.js new file mode 100644 index 0000000..1f03afe --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/App.test.js @@ -0,0 +1,8 @@ +import { render, screen } from '@testing-library/react'; +import App from './App'; + +test('renders learn react link', () => { + render(); + const linkElement = screen.getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/components/WorkflowDefinitionEditor.js b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/components/WorkflowDefinitionEditor.js new file mode 100644 index 0000000..87297c7 --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/components/WorkflowDefinitionEditor.js @@ -0,0 +1,30 @@ +import React from "react"; +import {v4 as uuid} from "uuid"; + +export default class WorkflowDefinitionEditor extends React.Component { + + constructor(props) { + super(props); + + debugger; + + if (!this.props.id) + this.id = uuid(); + } + + id = ""; + + onValueChanged = function (value) { + }; + + render() { + return React.createElement('elsa-studio-workflow-definition-editor', { ...this.props, id: this.id, "definition-id": this.props.definitionId }); + } + + componentDidMount() { + let element = document.getElementById(this.id); + element.valueChanged = (x) => { + this.props.onValueChanged(x); + }; + } +} \ No newline at end of file diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/index.css b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/index.css new file mode 100644 index 0000000..ec2585e --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/index.js b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/index.js new file mode 100644 index 0000000..d563c0f --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/index.js @@ -0,0 +1,17 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import './index.css'; +import App from './App'; +import reportWebVitals from './reportWebVitals'; + +const root = ReactDOM.createRoot(document.getElementById('root')); +root.render( + + + +); + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/logo.svg b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/logo.svg new file mode 100644 index 0000000..9dfc1c0 --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/reportWebVitals.js b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/reportWebVitals.js new file mode 100644 index 0000000..5253d3a --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = onPerfEntry => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/setupTests.js b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/setupTests.js new file mode 100644 index 0000000..8f2609b --- /dev/null +++ b/samples/react/workflow-definition-editor-sample/workflow-definition-editor-app/src/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000..fc7ca96 --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/bundles/Elsa.Studio/Elsa.Studio.csproj b/src/bundles/Elsa.Studio/Elsa.Studio.csproj new file mode 100644 index 0000000..622a2d7 --- /dev/null +++ b/src/bundles/Elsa.Studio/Elsa.Studio.csproj @@ -0,0 +1,14 @@ + + + + Elsa Studio bundle of commonly used packages. + elsa studio framework bundle + + + + + + + + + diff --git a/src/bundles/Elsa.Studio/FodyWeavers.xml b/src/bundles/Elsa.Studio/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/bundles/Elsa.Studio/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/bundles/Elsa.Studio/FodyWeavers.xsd b/src/bundles/Elsa.Studio/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/bundles/Elsa.Studio/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/bundles/Elsa.Studio/Readme.md b/src/bundles/Elsa.Studio/Readme.md new file mode 100644 index 0000000..209c898 --- /dev/null +++ b/src/bundles/Elsa.Studio/Readme.md @@ -0,0 +1,8 @@ +# Elsa.Studio + +This is a bundle package that includes the following packages: + +- Elsa.Studio.Backend +- Elsa.Studio.Dashboard +- Elsa.Studio.Workflows +- Elsa.Studio.Shell \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core.BlazorServer/Elsa.Studio.Core.BlazorServer.csproj b/src/framework/Elsa.Studio.Core.BlazorServer/Elsa.Studio.Core.BlazorServer.csproj new file mode 100644 index 0000000..4f3ac09 --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorServer/Elsa.Studio.Core.BlazorServer.csproj @@ -0,0 +1,18 @@ + + + + Blazor Server impementation for certain abstractions provided by Elsa.Studio.Core. + elsa studio blazor server + + + + + + + + + + + + + diff --git a/src/framework/Elsa.Studio.Core.BlazorServer/Extensions/ServiceCollectionExtensions.cs b/src/framework/Elsa.Studio.Core.BlazorServer/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..3dbfbab --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorServer/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,23 @@ +using Elsa.Studio.Core.BlazorServer.HostedServices; +using Elsa.Studio.Extensions; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Core.BlazorServer.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds core services with Blazor Server implementations. + /// + public static IServiceCollection AddCore(this IServiceCollection services) + { + services.AddCoreInternal(); + services.AddSharedServices(); + services.AddHostedService(); + + return services; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core.BlazorServer/FodyWeavers.xml b/src/framework/Elsa.Studio.Core.BlazorServer/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorServer/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core.BlazorServer/FodyWeavers.xsd b/src/framework/Elsa.Studio.Core.BlazorServer/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorServer/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core.BlazorServer/HostedServices/RunStartupTasksHostedService.cs b/src/framework/Elsa.Studio.Core.BlazorServer/HostedServices/RunStartupTasksHostedService.cs new file mode 100644 index 0000000..a491976 --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorServer/HostedServices/RunStartupTasksHostedService.cs @@ -0,0 +1,37 @@ +using Elsa.Studio.Contracts; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace Elsa.Studio.Core.BlazorServer.HostedServices; + +/// +/// Executes all registered services. +/// +public class RunStartupTasksHostedService : IHostedService +{ + private readonly IServiceScopeFactory _serviceScopeFactory; + + /// + /// Initializes a new instance of . + /// + /// + public RunStartupTasksHostedService(IServiceScopeFactory serviceScopeFactory) + { + _serviceScopeFactory = serviceScopeFactory; + } + + + /// + /// Resolves all registered services and executes them. + /// + public async Task StartAsync(CancellationToken cancellationToken) + { + using var scope = _serviceScopeFactory.CreateScope(); + var startupTaskRunner = scope.ServiceProvider.GetRequiredService(); + + await startupTaskRunner.RunStartupTasksAsync(cancellationToken); + } + + /// + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core.BlazorWasm/Elsa.Studio.Core.BlazorWasm.csproj b/src/framework/Elsa.Studio.Core.BlazorWasm/Elsa.Studio.Core.BlazorWasm.csproj new file mode 100644 index 0000000..8086486 --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorWasm/Elsa.Studio.Core.BlazorWasm.csproj @@ -0,0 +1,17 @@ + + + + Blazor WebAssembly impementation for certain abstractions provided by Elsa.Studio.Core. + elsa studio blazor webassembly + + + + + + + + + + + + diff --git a/src/framework/Elsa.Studio.Core.BlazorWasm/Extensions/ServiceCollectionExtensions.cs b/src/framework/Elsa.Studio.Core.BlazorWasm/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..7460896 --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorWasm/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,21 @@ +using Elsa.Studio.Extensions; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Core.BlazorWasm.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds core services with WASM implementations. + /// + public static IServiceCollection AddCore(this IServiceCollection services) + { + services.AddSharedServices(); + services.AddCoreInternal(); + + return services; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core.BlazorWasm/FodyWeavers.xml b/src/framework/Elsa.Studio.Core.BlazorWasm/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorWasm/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core.BlazorWasm/FodyWeavers.xsd b/src/framework/Elsa.Studio.Core.BlazorWasm/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/framework/Elsa.Studio.Core.BlazorWasm/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Abstractions/FeatureBase.cs b/src/framework/Elsa.Studio.Core/Abstractions/FeatureBase.cs new file mode 100644 index 0000000..3a22ba9 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Abstractions/FeatureBase.cs @@ -0,0 +1,12 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Abstractions; + +/// +/// A base class for modules. +/// +public abstract class FeatureBase : IFeature +{ + /// + public virtual ValueTask InitializeAsync(CancellationToken cancellationToken = default) => ValueTask.CompletedTask; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Abstractions/FieldExtensionHandlerBase.cs b/src/framework/Elsa.Studio.Core/Abstractions/FieldExtensionHandlerBase.cs new file mode 100644 index 0000000..fc97ef5 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Abstractions/FieldExtensionHandlerBase.cs @@ -0,0 +1,54 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Enums; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Abstractions; + +/// +/// Provides a base handler for field extensions. +/// +public abstract class FieldExtensionHandlerBase : IUIFieldExtensionHandler +{ + /// + /// + /// + public virtual int DisplayOrder { get; set; } = 1; + + /// + /// + /// + public virtual bool IncludeForAll { get; set; } = false; + + /// + /// + /// + public virtual FieldExtensionPosition Position { get; set; } = FieldExtensionPosition.Top; + + /// + /// + /// + public virtual string UIHintComponent { get; set; } = string.Empty; + + /// + /// + /// + public virtual List ActivityTypes { get; set; } = []; + + /// + /// + /// + public virtual List Syntaxes { get; set; } = []; + + /// + /// + /// + public virtual bool GetExtensionForInputComponent(string componentName) => + (string.IsNullOrEmpty(UIHintComponent) && !ActivityTypes.Any() && !Syntaxes.Any() && IncludeForAll) + || UIHintComponent.Equals(componentName, StringComparison.OrdinalIgnoreCase); + + /// + /// + /// + public abstract RenderFragment DisplayExtension(DisplayInputEditorContext context); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Attributes/RemoteFeatureAttribute.cs b/src/framework/Elsa.Studio.Core/Attributes/RemoteFeatureAttribute.cs new file mode 100644 index 0000000..89a6b80 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Attributes/RemoteFeatureAttribute.cs @@ -0,0 +1,18 @@ +namespace Elsa.Studio.Attributes; + +/// +/// Marks a class as a remote feature. +/// +public class RemoteFeatureAttribute : Attribute +{ + /// + public RemoteFeatureAttribute(string name) + { + Name = name; + } + + /// + /// Gets the name of the remote feature. + /// + public string Name { get; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IActivityTab.cs b/src/framework/Elsa.Studio.Core/Contracts/IActivityTab.cs new file mode 100644 index 0000000..e2b767a --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IActivityTab.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Components; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Elsa.Studio.Contracts; + +public interface IActivityTab +{ + string Title { get; } + + Func, RenderFragment> Render { get; } +} diff --git a/src/framework/Elsa.Studio.Core/Contracts/IAppBarService.cs b/src/framework/Elsa.Studio.Core/Contracts/IAppBarService.cs new file mode 100644 index 0000000..2e80d2e --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IAppBarService.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Contracts; + +public interface IAppBarService +{ + /// + /// Invoked when the app bar items change. + /// + event Action AppBarItemsChanged; + + /// + /// A collection of components to render in the app bar. + /// + IEnumerable AppBarItems { get; } + + /// + /// Adds a component to the app bar. + /// + /// The type of the component. + void AddAppBarItem() where T : IComponent; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IBackendApiClientProvider.cs b/src/framework/Elsa.Studio.Core/Contracts/IBackendApiClientProvider.cs new file mode 100644 index 0000000..0e699cc --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IBackendApiClientProvider.cs @@ -0,0 +1,19 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Provides connection details to the backend. +/// +public interface IBackendApiClientProvider +{ + /// + /// Gets the URL to the backend. + /// + Uri Url { get; } + + /// + /// Gets an API client from the backend connection provider. + /// + /// The API client type. + /// The API client. + ValueTask GetApiAsync(CancellationToken cancellationToken = default) where T : class; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IBlazorServiceAccessor.cs b/src/framework/Elsa.Studio.Core/Contracts/IBlazorServiceAccessor.cs new file mode 100644 index 0000000..f9425da --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IBlazorServiceAccessor.cs @@ -0,0 +1,10 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Represents an interface for accessing the current IServiceProvider in Blazor. +/// +public interface IBlazorServiceAccessor +{ + /// Gets or sets the current IServiceProvider. + IServiceProvider Services { get; set; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IClientInformationProvider.cs b/src/framework/Elsa.Studio.Core/Contracts/IClientInformationProvider.cs new file mode 100644 index 0000000..b0d406e --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IClientInformationProvider.cs @@ -0,0 +1,14 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides information about the client. +/// +public interface IClientInformationProvider +{ + /// + /// Gets information about the client. + /// + ValueTask GetInfoAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IExpressionProvider.cs b/src/framework/Elsa.Studio.Core/Contracts/IExpressionProvider.cs new file mode 100644 index 0000000..79359e1 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IExpressionProvider.cs @@ -0,0 +1,14 @@ +using Elsa.Api.Client.Resources.Scripting.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides available expression descriptors. +/// +public interface IExpressionProvider +{ + /// + /// Lists all expression descriptors. + /// + ValueTask> ListAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IExpressionService.cs b/src/framework/Elsa.Studio.Core/Contracts/IExpressionService.cs new file mode 100644 index 0000000..3950dc4 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IExpressionService.cs @@ -0,0 +1,19 @@ +using Elsa.Api.Client.Resources.Scripting.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides syntax services. +/// +public interface IExpressionService +{ + /// + /// Lists all expression descriptors. + /// + Task> ListDescriptorsAsync(CancellationToken cancellationToken = default); + + /// + /// Gets a syntax provider by name. + /// + Task GetByTypeAsync(string type, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IFeature.cs b/src/framework/Elsa.Studio.Core/Contracts/IFeature.cs new file mode 100644 index 0000000..5d6d292 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IFeature.cs @@ -0,0 +1,13 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Represents a feature that can be registered with the dashboard. +/// +public interface IFeature +{ + /// + /// Called by the dashboard to initialize the feature. + /// + /// A cancellation token. + ValueTask InitializeAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IFeatureService.cs b/src/framework/Elsa.Studio.Core/Contracts/IFeatureService.cs new file mode 100644 index 0000000..a068d37 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IFeatureService.cs @@ -0,0 +1,22 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Manages features. +/// +public interface IFeatureService +{ + /// + /// Event that is triggered when the features have been initialized. + /// + event Action? Initialized; + + /// + /// Returns all features. + /// + IEnumerable GetFeatures(); + + /// + /// Initializes all features. + /// + Task InitializeFeaturesAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IMediator.cs b/src/framework/Elsa.Studio.Core/Contracts/IMediator.cs new file mode 100644 index 0000000..fb40357 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IMediator.cs @@ -0,0 +1,30 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Represents a mediator that can be used to publish notifications and subscribe to notifications. +/// +public interface IMediator +{ + /// + /// Subscribes to a notification. + /// + /// + /// + /// + void Subscribe(THandler handler) where THandler : INotificationHandler where TNotification : INotification; + + /// + /// Unsubscribes from a notification. + /// + void Unsubscribe(THandler handler) where THandler : INotificationHandler where TNotification : INotification; + + /// + /// Unsubscribes from a notification. + /// + void Unsubscribe(INotificationHandler handler); + + /// + /// Publishes a notification. + /// + Task NotifyAsync(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IMenuGroupProvider.cs b/src/framework/Elsa.Studio.Core/Contracts/IMenuGroupProvider.cs new file mode 100644 index 0000000..9bf5d88 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IMenuGroupProvider.cs @@ -0,0 +1,16 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Returns menu item groups to the dashboard. +/// +public interface IMenuGroupProvider +{ + /// + /// Returns menu item groups to the dashboard. + /// + /// The cancellation token. + /// A collection of instances. + ValueTask> GetMenuGroupsAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IMenuProvider.cs b/src/framework/Elsa.Studio.Core/Contracts/IMenuProvider.cs new file mode 100644 index 0000000..c1a0e85 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IMenuProvider.cs @@ -0,0 +1,10 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio.Contracts; + +/// Provides menu items to the dashboard. +public interface IMenuProvider +{ + /// Returns a list of menu items. + ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IMenuService.cs b/src/framework/Elsa.Studio.Core/Contracts/IMenuService.cs new file mode 100644 index 0000000..0509064 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IMenuService.cs @@ -0,0 +1,23 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// A service that provides menu items and menu item groups. +/// +public interface IMenuService +{ + /// + /// Returns all menu items from all menu providers. + /// + /// The cancellation token. + /// A list of instances. + ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default); + + /// + /// Returns all menu item groups from all menu group providers. + /// + /// The cancellation token. + /// A list of instances. + ValueTask> GetMenuItemGroupsAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/INotification.cs b/src/framework/Elsa.Studio.Core/Contracts/INotification.cs new file mode 100644 index 0000000..71585a6 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/INotification.cs @@ -0,0 +1,5 @@ +namespace Elsa.Studio.Contracts; + +public interface INotification +{ +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/INotificationHandler.cs b/src/framework/Elsa.Studio.Core/Contracts/INotificationHandler.cs new file mode 100644 index 0000000..3e4e678 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/INotificationHandler.cs @@ -0,0 +1,22 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Represents a notification handler. +/// +public interface INotificationHandler +{ +} + +/// +/// Represents a notification handler. +/// +/// The type of the notification. +public interface INotificationHandler : INotificationHandler where T : INotification +{ + /// + /// Handles the given notification. + /// + /// The notification to handle. + /// The cancellation token. + Task HandleAsync(T notification, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IRemoteBackendAccessor.cs b/src/framework/Elsa.Studio.Core/Contracts/IRemoteBackendAccessor.cs new file mode 100644 index 0000000..4e087f8 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IRemoteBackendAccessor.cs @@ -0,0 +1,14 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides access to the current remote backend. +/// +public interface IRemoteBackendAccessor +{ + /// + /// Gets or sets the current backend. + /// + RemoteBackend RemoteBackend { get; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IRemoteFeatureProvider.cs b/src/framework/Elsa.Studio.Core/Contracts/IRemoteFeatureProvider.cs new file mode 100644 index 0000000..433ca0a --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IRemoteFeatureProvider.cs @@ -0,0 +1,22 @@ +using Elsa.Api.Client.Resources.Features.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides a way to check if a feature is enabled. +/// +public interface IRemoteFeatureProvider +{ + /// + /// Returns a value indicating whether the feature with the specified name is enabled. + /// + /// The name of the feature. + /// An optional cancellation token. + /// A value indicating whether the feature with the specified name is enabled. + Task IsEnabledAsync(string featureName, CancellationToken cancellationToken = default); + + /// + /// Returns a list of installed features. + /// + Task> ListAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IServerInformationProvider.cs b/src/framework/Elsa.Studio.Core/Contracts/IServerInformationProvider.cs new file mode 100644 index 0000000..e06abb2 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IServerInformationProvider.cs @@ -0,0 +1,14 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides information about the server. +/// +public interface IServerInformationProvider +{ + /// + /// Gets information about the server. + /// + ValueTask GetInfoAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IStartupTask.cs b/src/framework/Elsa.Studio.Core/Contracts/IStartupTask.cs new file mode 100644 index 0000000..200d635 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IStartupTask.cs @@ -0,0 +1,13 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Represents a startup task that is invoked once during application startup. +/// +public interface IStartupTask +{ + /// + /// Invoked during application startup. + /// + /// A cancellation token. + ValueTask ExecuteAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IStartupTaskRunner.cs b/src/framework/Elsa.Studio.Core/Contracts/IStartupTaskRunner.cs new file mode 100644 index 0000000..71dbebe --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IStartupTaskRunner.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Runs startup tasks. +/// +public interface IStartupTaskRunner +{ + /// + /// Runs startup tasks. + /// + Task RunStartupTasksAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IThemeService.cs b/src/framework/Elsa.Studio.Core/Contracts/IThemeService.cs new file mode 100644 index 0000000..a5e6d04 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IThemeService.cs @@ -0,0 +1,36 @@ +using MudBlazor; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides theme information to the dashboard. +/// +public interface IThemeService +{ + /// + /// Raised when the current theme changes. + /// + event Action CurrentThemeChanged; + + /// + /// Raised when the dark mode changes. + /// + event Action IsDarkModeChanged; + + /// + /// The current theme. + /// + MudTheme CurrentTheme { get; set; } + + /// + /// Returns the current palette, depending on whether the dashboard is in dark mode. + /// +#pragma warning disable CS0618 + Palette CurrentPalette => IsDarkMode ? CurrentTheme.PaletteDark : CurrentTheme.PaletteLight; +#pragma warning restore CS0618 + + /// + /// Whether the dashboard is in dark mode. + /// + public bool IsDarkMode { get; set; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IUIFieldExtensionHandler.cs b/src/framework/Elsa.Studio.Core/Contracts/IUIFieldExtensionHandler.cs new file mode 100644 index 0000000..6a4e080 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IUIFieldExtensionHandler.cs @@ -0,0 +1,52 @@ +using Elsa.Studio.Enums; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Contracts +{ + /// + /// Provides a contract for UI field extension handlers. + /// + public interface IUIFieldExtensionHandler + { + /// + /// The order in which the extensions should be displayed. + /// + int DisplayOrder { get; set; } + + /// + /// If set to true and no restricting types are set, either with UIHintComponent, ActivityTypes or Syntaxes, this extension will be rendered for in all field types. + /// + bool IncludeForAll { get; set; } + + /// + /// The position to render the extension within the field. + /// + FieldExtensionPosition Position { get; set; } + + /// + /// The UIHint component this extension should be rendered for. + /// + string UIHintComponent { get; set; } + + /// + /// The activities this extension should be rendered for. + /// + List ActivityTypes { get; set; } + + /// + /// The syntaxes this extension should be rendered for. + /// + List Syntaxes { get; set; } + + /// + /// Returns true if the handler extension the specified or is empty. + /// + bool GetExtensionForInputComponent(string componentName); + + /// + /// Returns a of the added extension. + /// + RenderFragment DisplayExtension(DisplayInputEditorContext context); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IUIFieldExtensionService.cs b/src/framework/Elsa.Studio.Core/Contracts/IUIFieldExtensionService.cs new file mode 100644 index 0000000..68ad356 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IUIFieldExtensionService.cs @@ -0,0 +1,17 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides a service contact for resolving UI field extensions +/// +public interface IUIFieldExtensionService +{ + /// + /// Try to return a list of extension handlers for a component + /// + /// The component name to get the handler for. This should be the name of the component calling this function. + /// The display input editor context + /// + List? TryGetHandlers(string componentName, DisplayInputEditorContext context); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IUIHintHandler.cs b/src/framework/Elsa.Studio.Core/Contracts/IUIHintHandler.cs new file mode 100644 index 0000000..6ede80e --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IUIHintHandler.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides a contract for UI hint handlers. +/// +public interface IUIHintHandler +{ + /// + /// Returns true if the handler supports the specified UI hint. + /// + bool GetSupportsUIHint(string uiHint); + + /// + /// Returns the UI syntax for the handler. + /// + string UISyntax { get; } + + /// + /// Returns a that renders the input editor. + /// + RenderFragment DisplayInputEditor(DisplayInputEditorContext context); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IUIHintService.cs b/src/framework/Elsa.Studio.Core/Contracts/IUIHintService.cs new file mode 100644 index 0000000..37c1030 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IUIHintService.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Contracts; + +public interface IUIHintService +{ + IUIHintHandler GetHandler(string uiHint); + //RenderFragment DisplayInputEditor(DisplayInputEditorContext context); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IUnauthorizedComponentProvider.cs b/src/framework/Elsa.Studio.Core/Contracts/IUnauthorizedComponentProvider.cs new file mode 100644 index 0000000..c3b5311 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IUnauthorizedComponentProvider.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Contracts; + +/// +/// Provides the to display the login page. +/// +public interface IUnauthorizedComponentProvider +{ + /// + /// Returns the to display the login page. + /// + RenderFragment GetUnauthorizedComponent(); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Contracts/IWidget.cs b/src/framework/Elsa.Studio.Core/Contracts/IWidget.cs new file mode 100644 index 0000000..6bac207 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IWidget.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Contracts; + +/// +/// Represents a widget. +/// +public interface IWidget +{ + /// + /// Gets the zone in which the widget should be rendered. + /// + string Zone { get; } + + /// + /// Gets the order in which the widget should be rendered. + /// + double Order { get; } + + /// + /// Gets the fragment to render. + /// + Func, RenderFragment> Render { get; } +} + diff --git a/src/framework/Elsa.Studio.Core/Contracts/IWidgetRegistry.cs b/src/framework/Elsa.Studio.Core/Contracts/IWidgetRegistry.cs new file mode 100644 index 0000000..1dbbef7 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Contracts/IWidgetRegistry.cs @@ -0,0 +1,17 @@ +namespace Elsa.Studio.Contracts; + +/// +/// Provides a registry of widgets. +/// +public interface IWidgetRegistry +{ + /// + /// Adds the specified widget to the registry. + /// + void Add(IWidget widget); + + /// + /// Returns a list of widgets for the specified zone. + /// + IEnumerable List(string zone); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Elsa.Studio.Core.csproj b/src/framework/Elsa.Studio.Core/Elsa.Studio.Core.csproj new file mode 100644 index 0000000..a87df28 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Elsa.Studio.Core.csproj @@ -0,0 +1,36 @@ + + + + Core Elsa Studio services. + elsa studio core + Elsa.Studio + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/framework/Elsa.Studio.Core/ElsaStudioIcons.cs b/src/framework/Elsa.Studio.Core/ElsaStudioIcons.cs new file mode 100644 index 0000000..b2bd2dc --- /dev/null +++ b/src/framework/Elsa.Studio.Core/ElsaStudioIcons.cs @@ -0,0 +1,41 @@ +namespace Elsa.Studio; + +/// +/// Provides Elsa Studio icons. +/// +public static class ElsaStudioIcons +{ + /// + /// Provides Tabler icons. + /// + public static class Tabler + { + public const string Pencil = """ """; + public const string Text = """ """; + public const string Cloud = """ """; + public const string SwitchDiagonal = """ """; + public const string CheckCircle = """ """; + public const string CheckShield = """ """; + public const string Hexagon = """ """; + public const string GitMerge = """ """; + public const string GitFork = """ """; + public const string World = """ """; + public const string RepeatOne = """ """; + public const string Back1 = """ """; + public const string Italic = """ """; + public const string RotateClockwise2 = """ """; + } + + /// + /// Provides Heroicons. + /// + public static class Heroicons + { + public const string Question = """"""; + public const string Exclamation = """"""; + public const string PencilPaper = """"""; + + public const string Outgoing = """"""; + public const string Incoming = """"""; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Enums/FieldExtensionPosition.cs b/src/framework/Elsa.Studio.Core/Enums/FieldExtensionPosition.cs new file mode 100644 index 0000000..dea864e --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Enums/FieldExtensionPosition.cs @@ -0,0 +1,17 @@ +namespace Elsa.Studio.Enums; + +/// +/// Provides field extension render positions. +/// +public enum FieldExtensionPosition +{ + /// + /// Positions the extension at the top of the field. + /// + Top = 0, + + /// + /// Positions the extension at the bottom of the field. + /// + Bottom = 1 +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Extensions/MediatorExtensions.cs b/src/framework/Elsa.Studio.Core/Extensions/MediatorExtensions.cs new file mode 100644 index 0000000..bca4133 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Extensions/MediatorExtensions.cs @@ -0,0 +1,39 @@ +using Elsa.Studio.Contracts; +using JetBrains.Annotations; + +namespace Elsa.Studio.Extensions; + +/// +/// Contains extension methods for . +/// +[UsedImplicitly] +public static class MediatorExtensions +{ + /// + /// Subscribes the given handler to the given notification. + /// Use this from components' Initialize methods. + /// The component itself can be the handler + /// to subscribe itself if it implements . + /// + public static void Subscribe(this IMediator mediator, INotificationHandler handler) where TNotification : INotification + { + var handlerType = handler.GetType(); + var subscribeMethod = typeof(IMediator).GetMethod(nameof(IMediator.Subscribe))!; + var genericSubscribeMethod = subscribeMethod.MakeGenericMethod(typeof(TNotification), handlerType); + genericSubscribeMethod.Invoke(mediator, [handler]); + } + + /// + /// Unsubscribes the given handler from the given notification. + /// Use this from components' Dispose methods. + /// The component itself can be the handler + /// to unsubscribe itself if it implements . + /// + public static void Unsubscribe(this IMediator mediator, INotificationHandler handler) where TNotification : INotification + { + var handlerType = handler.GetType(); + var unsubscribeMethod = typeof(IMediator).GetMethod(nameof(IMediator.Unsubscribe))!; + var genericUnsubscribeMethod = unsubscribeMethod.MakeGenericMethod(typeof(TNotification), handlerType); + genericUnsubscribeMethod.Invoke(mediator, [handler]); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Extensions/ObjectExtension.cs b/src/framework/Elsa.Studio.Core/Extensions/ObjectExtension.cs new file mode 100644 index 0000000..a0365d0 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Extensions/ObjectExtension.cs @@ -0,0 +1,33 @@ +using System.Reflection; + +namespace Elsa.Studio.Extensions; + +/// +/// Provides extension methods for the class. +/// +public static class ObjectExtension +{ + /// + /// Converts the specified object to a dictionary. + /// + /// + /// + /// + public static Dictionary ToDictionary(this object obj) + { + if (obj == null) + throw new ArgumentNullException(nameof(obj)); + + var dictionary = new Dictionary(); + foreach (var property in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + if (!property.CanRead) + continue; + + var value = property.GetValue(obj); + dictionary.Add(property.Name, value); + } + + return dictionary; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Extensions/RateLimitedFuncExtensions.cs b/src/framework/Elsa.Studio.Core/Extensions/RateLimitedFuncExtensions.cs new file mode 100644 index 0000000..5e27c97 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Extensions/RateLimitedFuncExtensions.cs @@ -0,0 +1,31 @@ +using ThrottleDebounce; + +namespace Elsa.Studio.Extensions; + +/// +/// Adds extension methods for and . +/// +public static class RateLimitedFuncExtensions +{ + /// + /// Invokes the specified rate limited function. + /// + public static async Task InvokeAsync(this RateLimitedFunc rateLimitedFunc) + { + var task = rateLimitedFunc.Invoke(); + + if (task != null) + await task; + } + + /// + /// Invokes the specified rate limited function. + /// + public static async Task InvokeAsync(this RateLimitedFunc rateLimitedFunc, T arg1) + { + var task = rateLimitedFunc.Invoke(arg1); + + if (task != null) + await task; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Extensions/RenderTreeBuilderExtensions.cs b/src/framework/Elsa.Studio.Core/Extensions/RenderTreeBuilderExtensions.cs new file mode 100644 index 0000000..e657479 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Extensions/RenderTreeBuilderExtensions.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Rendering; + +namespace Elsa.Studio.Extensions; + +/// +/// Provides extension methods for the class. +/// +public static class RenderTreeBuilderExtensions +{ + /// + /// Creates a component of the specified type. + /// + public static void CreateComponent(this RenderTreeBuilder builder) where T : IComponent + { + var sequence = 0; + CreateComponent(builder, ref sequence); + } + + /// + /// Creates a component of the specified type. + /// + public static void CreateComponent(this RenderTreeBuilder builder, ref int sequence) where T : IComponent + { + builder.OpenComponent(sequence++); + builder.CloseComponent(); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Extensions/ServiceCollectionExtensions.cs b/src/framework/Elsa.Studio.Core/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..9cf6169 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,90 @@ +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Options; +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.Models; +using Elsa.Studio.Options; +using Elsa.Studio.Services; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Elsa.Studio.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the core services. + /// + public static IServiceCollection AddCoreInternal(this IServiceCollection services) + { + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + ; + + // Mediator. + services.AddScoped(); + + //Localization + services.AddSingleton(); + services.AddSingleton(); + return services; + } + + /// + /// Adds backend services to the service collection. + /// + public static IServiceCollection AddRemoteBackend(this IServiceCollection services, BackendApiConfig? config = null) + { + services.Configure(config?.ConfigureBackendOptions ?? (_ => { })); + services.AddDefaultApiClients(config?.ConfigureHttpClientBuilder); + services.TryAddScoped(); + services.TryAddScoped(); + return services; + } + + public static IServiceCollection AddRemoteApi(this IServiceCollection services, BackendApiConfig? config = null) where TApi : class + { + services.Configure(config?.ConfigureBackendOptions ?? (_ => { })); + services.AddApiClient(config?.ConfigureHttpClientBuilder); + return services; + } + + /// + /// Adds the specified . + /// + public static IServiceCollection AddNotificationHandler(this IServiceCollection services) where T: class, INotificationHandler + { + return services.AddScoped(); + } + + /// + /// Adds the specified . + /// + public static IServiceCollection AddUIHintHandler(this IServiceCollection services) where T : class, IUIHintHandler + { + return services.AddScoped(); + } + + /// + /// Adds the specified . + /// + public static IServiceCollection AddUIFieldEnhancerHandler(this IServiceCollection services) where T : class, IUIFieldExtensionHandler + { + return services.AddScoped(); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/FodyWeavers.xml b/src/framework/Elsa.Studio.Core/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/framework/Elsa.Studio.Core/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/FodyWeavers.xsd b/src/framework/Elsa.Studio.Core/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/framework/Elsa.Studio.Core/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Localization/DefaultLocalizationProvider.cs b/src/framework/Elsa.Studio.Core/Localization/DefaultLocalizationProvider.cs new file mode 100644 index 0000000..1296549 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Localization/DefaultLocalizationProvider.cs @@ -0,0 +1,9 @@ +namespace Elsa.Studio.Localization; + +internal class DefaultLocalizationProvider : ILocalizationProvider +{ + public string GetTranslation(string key) + { + return key; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Localization/DefaultLocalizer.cs b/src/framework/Elsa.Studio.Core/Localization/DefaultLocalizer.cs new file mode 100644 index 0000000..937a8d9 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Localization/DefaultLocalizer.cs @@ -0,0 +1,58 @@ +using Microsoft.Extensions.Localization; + +namespace Elsa.Studio.Localization; + +/// +public class DefaultLocalizer(ILocalizationProvider provider) : ILocalizer +{ + /// + public LocalizedString this[string key] + { + get + { + if (string.IsNullOrWhiteSpace(key)) + return new LocalizedString(string.Empty, string.Empty, true); + + var notFound = false; + var translation = provider.GetTranslation(key); + + if (string.IsNullOrEmpty(translation)) + { + translation = key; + notFound = true; + } + + return new LocalizedString(key, translation, notFound); + } + } + + /// + /// Gets the localized string with the specified key and formats it with the provided arguments. + /// + /// The key of the localized string. + /// The arguments to format the localized string with. + /// The localized string formatted with the provided arguments. + public LocalizedString this[string key, params object[] arguments] + { + get + { + if (string.IsNullOrWhiteSpace(key)) + return new LocalizedString(string.Empty, string.Empty, true); + + var notFound = false; + var translation = provider.GetTranslation(key); + + if (string.IsNullOrEmpty(translation)) + { + translation = string.Format(key, arguments); + notFound = true; + } + else + { + translation = string.Format(translation, arguments); + } + + return new LocalizedString(key, translation, notFound); + } + } +} diff --git a/src/framework/Elsa.Studio.Core/Localization/ILocalizationProvider.cs b/src/framework/Elsa.Studio.Core/Localization/ILocalizationProvider.cs new file mode 100644 index 0000000..dd31284 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Localization/ILocalizationProvider.cs @@ -0,0 +1,6 @@ +namespace Elsa.Studio.Localization; + +public interface ILocalizationProvider +{ + string GetTranslation(string key); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Localization/ILocalizer.cs b/src/framework/Elsa.Studio.Core/Localization/ILocalizer.cs new file mode 100644 index 0000000..085ca26 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Localization/ILocalizer.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Localization; + +namespace Elsa.Studio.Localization; + +/// +/// Interface for localization. +/// +public interface ILocalizer +{ + /// + /// Gets the localized string for the given key. + /// + /// The key for the localized string. + LocalizedString this[string key] { get; } + + /// + /// Gets the localized string for the given key and formats it with the provided arguments. + /// + /// The key for the localized string. + /// The arguments to format the localized string with. + LocalizedString this[string key, params object[] arguments] { get; } +} diff --git a/src/framework/Elsa.Studio.Core/MenuItemGroups.cs b/src/framework/Elsa.Studio.Core/MenuItemGroups.cs new file mode 100644 index 0000000..1cb6f9f --- /dev/null +++ b/src/framework/Elsa.Studio.Core/MenuItemGroups.cs @@ -0,0 +1,9 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio; + +public static class MenuItemGroups +{ + public static readonly MenuItemGroup General = new("general", "General", 0f); + public static readonly MenuItemGroup Settings = new("security", "Settings", 1000f); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Models/BackendApiConfig.cs b/src/framework/Elsa.Studio.Core/Models/BackendApiConfig.cs new file mode 100644 index 0000000..bd80646 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Models/BackendApiConfig.cs @@ -0,0 +1,10 @@ +using Elsa.Api.Client.Options; +using Elsa.Studio.Options; + +namespace Elsa.Studio.Models; + +public class BackendApiConfig +{ + public Action? ConfigureHttpClientBuilder { get; set; } + public Action? ConfigureBackendOptions { get; set; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Models/ClientInformation.cs b/src/framework/Elsa.Studio.Core/Models/ClientInformation.cs new file mode 100644 index 0000000..330e698 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Models/ClientInformation.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Models; + +/// +/// Contains information about the client. +/// +/// The installed package version of Elsa Studio. +public record ClientInformation(string PackageVersion); \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Models/DisplayInputEditorContext.cs b/src/framework/Elsa.Studio.Core/Models/DisplayInputEditorContext.cs new file mode 100644 index 0000000..2a0de6c --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Models/DisplayInputEditorContext.cs @@ -0,0 +1,198 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Models; + +/// +/// Provides contextual information to the input editor. +/// +public class DisplayInputEditorContext +{ + /// + /// The workflow definition. + /// + public WorkflowDefinition WorkflowDefinition { get; set; } = null!; + + /// + /// The activity. + /// + public JsonObject Activity { get; set; } = null!; + + /// + /// The activity descriptor. + /// + public ActivityDescriptor ActivityDescriptor { get; set; } = null!; + + /// + /// The input descriptor. + /// + public InputDescriptor InputDescriptor { get; set; } = null!; + + /// + /// The input value. + /// + public object? Value { get; set; } + + /// + /// The UI hint handler. + /// + public IUIHintHandler UIHintHandler { get; set; } = null!; + + /// + /// The syntax provider. + /// + public ExpressionDescriptor? SelectedExpressionDescriptor { get; set; } + + /// + /// A delegate that is invoked when the input value changes. + /// + public Func OnValueChanged { get; set; } = null!; + + /// + /// A value indicating whether the input is read-only. + /// + public bool IsReadOnly { get; set; } + + /// + /// Returns the input value or the default value if the input value is null. + /// + public T? GetValueOrDefault() + { + return (Value ?? InputDescriptor.DefaultValue).ConvertTo(); + } + + /// + /// Returns the wrapped input literal value. + /// + /// + public string GetLiteralValueOrDefault() + { + if (!InputDescriptor.IsWrapped) + return Value?.ToString() ?? InputDescriptor.DefaultValue?.ToString() ?? string.Empty; + + var wrappedInput = Value as WrappedInput; + var expression = wrappedInput?.Expression; + + if (expression?.Type != "Literal") + return InputDescriptor.DefaultValue?.ToString() ?? string.Empty; + + var value = expression.Value; + return value?.ToString() ?? InputDescriptor.DefaultValue?.ToString() ?? string.Empty; + } + + /// + /// Returns the wrapped input object value. + /// + /// + public string GetObjectValueOrDefault() + { + if (!InputDescriptor.IsWrapped) + return Serialize(Value ?? InputDescriptor.DefaultValue); + + var wrappedInput = Value as WrappedInput; + var expression = wrappedInput?.Expression; + + if (expression?.Type != "Object") + return Serialize(InputDescriptor.DefaultValue); + + var value = expression.Value; + return value?.ToString() ?? InputDescriptor.DefaultValue?.ToString() ?? string.Empty; + } + + /// + /// Returns the input expression value if this is a wrapped input (i.e. Input{T}) or naked value otherwise. If either value is null, the default value is returned. + /// + public string GetExpressionValueOrDefault() + { + if (!InputDescriptor.IsWrapped) + return Value?.ToString() ?? InputDescriptor.DefaultValue?.ToString() ?? string.Empty; + + var wrappedInput = Value as WrappedInput; + var expression = wrappedInput?.Expression; + var value = expression?.ToString(); + return value ?? InputDescriptor.DefaultValue?.ToString() ?? string.Empty; + } + + /// + /// Updates the naked input value. + /// + public async Task UpdateValueAsync(object? value) + { + await OnValueChanged(value); + } + + /// + /// Updates the wrapped input expression. + /// + /// + public async Task UpdateExpressionAsync(Expression expression) + { + var wrappedInput = Value as WrappedInput; + + // Update input. + wrappedInput ??= new(); + wrappedInput.Expression = expression; + + Value = wrappedInput; + + // Notify that the input has changed. + await OnValueChanged(wrappedInput); + } + + /// + /// Updates the input value or sets it as a literal expression, + /// depending on the wrapping configuration of the . + /// + /// The new value to be set, either directly or wrapped as a literal expression. + public Task UpdateValueOrLiteralExpressionAsync(string value) + { + return UpdateValueOrExpressionAsync(value, _ => value, "Literal"); + } + + /// + /// Updates the input value or sets it as an object expression, + /// depending on the wrapping configuration of the . + /// + /// The new value to be set, either directly or wrapped as an object expression. + public Task UpdateValueOrObjectExpressionAsync(object value) + { + return UpdateValueOrExpressionAsync(value, Serialize, "Object"); + } + + /// + /// Updates the input value or sets it as an expression, + /// depending on the wrapping configuration of the . + /// + /// The new value to be set, either directly or wrapped as an expression. + /// A delegate to a function that stringifies the value for storing inside an object. + /// The expression type + public async Task UpdateValueOrExpressionAsync(object? value, Func toString, string expressionType) + { + if (InputDescriptor.IsWrapped) + { + var stringValue = toString(value); + var expression = new Expression(expressionType, stringValue); + + await UpdateExpressionAsync(expression); + return; + } + + await UpdateValueAsync(value); + } + + private static string Serialize(object? value) + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + return value != null ? JsonSerializer.Serialize(value, options) : string.Empty; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Models/MenuItem.cs b/src/framework/Elsa.Studio.Core/Models/MenuItem.cs new file mode 100644 index 0000000..6b8bff2 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Models/MenuItem.cs @@ -0,0 +1,44 @@ +using Microsoft.AspNetCore.Components.Routing; + +namespace Elsa.Studio.Models; + +/// +/// A menu item. +/// +public class MenuItem +{ + /// + /// The icon to use in SVG format. + /// + public string? Icon { get; set; } + + /// + /// The path to navigate to. + /// + public string Href { get; set; } = default!; + + /// + /// The to use. + /// + public NavLinkMatch Match { get; set; } = NavLinkMatch.Prefix; + + /// + /// The text to display. + /// + public string Text { get; set; } = default!; + + /// + /// The order of the menu item. + /// + public float Order { get; set; } + + /// + /// A list of sub menu items. + /// + public ICollection SubMenuItems { get; set; } = new List(); + + /// + /// The name of the group this menu item belongs to. + /// + public string GroupName { get; set; } = "General"; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Models/MenuItemGroup.cs b/src/framework/Elsa.Studio.Core/Models/MenuItemGroup.cs new file mode 100644 index 0000000..7b7a58f --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Models/MenuItemGroup.cs @@ -0,0 +1,4 @@ +namespace Elsa.Studio.Models; + +/// A menu item group. +public record MenuItemGroup(string Name, string Text, float Order = 0f); \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Models/RemoteBackend.cs b/src/framework/Elsa.Studio.Core/Models/RemoteBackend.cs new file mode 100644 index 0000000..321d11d --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Models/RemoteBackend.cs @@ -0,0 +1,21 @@ +namespace Elsa.Studio.Models; + +/// +/// Represent a remote backend. +/// +public class RemoteBackend +{ + /// + /// Initializes a new instance of the class. + /// + /// The URL of the backend. + public RemoteBackend(Uri url) + { + Url = url; + } + + /// + /// The URL of the backend. + /// + public Uri Url { get; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Models/Result.cs b/src/framework/Elsa.Studio.Core/Models/Result.cs new file mode 100644 index 0000000..4ac17d4 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Models/Result.cs @@ -0,0 +1,90 @@ +namespace Elsa.Studio.Models; + +/// +/// Represents a result that is either successful or failed. +/// +/// The type of the success value. +/// The type of the failure value. +public class Result +{ + /// + /// Creates a new successful result. + /// + public Result(TSuccess success) + { + Success = success; + } + + /// + /// Creates a new failed result. + /// + /// + public Result(TFailure failure) + { + Failure = failure; + } + + /// + /// The success value. + /// + public TSuccess? Success { get; set; } + + /// + /// The failure value. + /// + public TFailure? Failure { get; set; } + + /// + /// Returns true if the result is successful. + /// + public bool IsSuccess => Success is not null; + + /// + /// Returns true if the result is failed. + /// + public bool IsFailed => Failure is not null; + + /// + /// Invokes the specified handler if the result is successful. + /// + /// The success result. + public async Task OnSuccessAsync(Func handler) + { + if (!IsSuccess) return default!; + await handler(Success!); + return Success!; + } + + /// + /// Invokes the specified handler if the result is successful. + /// + /// The success result. + public TSuccess OnSuccess(Action handler) + { + if (!IsSuccess) return default!; + handler(Success!); + return Success!; + } + + /// + /// Invokes the specified handler if the result is failed. + /// + /// The failed result. + public async Task OnFailedAsync(Func handler) + { + if (!IsFailed) return default!; + await handler(Failure!); + return Failure!; + } + + /// + /// Invokes the specified handler if the result is failed. + /// + /// The failed result. + public TFailure OnFailed(Action handler) + { + if (!IsFailed) return default!; + handler(Failure!); + return Failure!; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Models/ServerInformation.cs b/src/framework/Elsa.Studio.Core/Models/ServerInformation.cs new file mode 100644 index 0000000..250b5bd --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Models/ServerInformation.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Models; + +/// +/// Contains information about the server. +/// +/// The installed package version of Elsa. +public record ServerInformation(string PackageVersion); \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Options/BackendOptions.cs b/src/framework/Elsa.Studio.Core/Options/BackendOptions.cs new file mode 100644 index 0000000..e20d9c0 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Options/BackendOptions.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Options; + +/// +/// Provides options about the backend. +/// +public class BackendOptions +{ + /// + /// The URL of the backend. + /// + public Uri Url { get; set; } = default!; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/AssemblyClientInformationProvider.cs b/src/framework/Elsa.Studio.Core/Services/AssemblyClientInformationProvider.cs new file mode 100644 index 0000000..a2c5ced --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/AssemblyClientInformationProvider.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; + +namespace Elsa.Studio.Services; + +/// +/// Provides client information by extracting metadata from the executing assembly. +/// +public class AssemblyClientInformationProvider : IClientInformationProvider +{ + /// + public ValueTask GetInfoAsync(CancellationToken cancellationToken = default) + { + var assembly = Assembly.GetExecutingAssembly(); + var versionAttribute = assembly.GetCustomAttribute(); + var version = RemoveAutoGeneratedPostfix(versionAttribute); + + return new(new ClientInformation(version)); + } + + private static string RemoveAutoGeneratedPostfix(AssemblyInformationalVersionAttribute? versionAttribute) + { + return versionAttribute?.InformationalVersion.Split("+")[0]!; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/BlazorScopedProxyApi.cs b/src/framework/Elsa.Studio.Core/Services/BlazorScopedProxyApi.cs new file mode 100644 index 0000000..e9bc00a --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/BlazorScopedProxyApi.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// +/// Decorates an API client with a Blazor service accessor, ensuring that the service provider is available to the API client when calling DI-resolved delegating handlers. +/// +public class BlazorScopedProxyApi : DispatchProxy +{ + private T _decoratedApi = default!; + private IBlazorServiceAccessor _blazorServiceAccessor = null!; + private IServiceProvider _serviceProvider = null!; + + /// + /// Initializes the BlazorScopedProxyApi instance with the specified parameters. + /// + /// The API client instance to be decorated. + /// The Blazor service accessor instance for setting the scoped service provider. + /// The service provider for dependency injection. + public void Initialize(T decoratedApi, IBlazorServiceAccessor blazorServiceAccessor, IServiceProvider serviceProvider) + { + _decoratedApi = decoratedApi; + _blazorServiceAccessor = blazorServiceAccessor; + _serviceProvider = serviceProvider; + } + + /// + protected override object? Invoke(MethodInfo? targetMethod, object?[]? args) + { + _blazorServiceAccessor.Services = _serviceProvider; + return targetMethod?.Invoke(_decoratedApi, args); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/BlazorServiceAccessor.cs b/src/framework/Elsa.Studio.Core/Services/BlazorServiceAccessor.cs new file mode 100644 index 0000000..0f6ec2a --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/BlazorServiceAccessor.cs @@ -0,0 +1,35 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// This class is used to access the IServiceProvider from a different DI scope. +/// See: https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-7.0#access-server-side-blazor-services-from-a-different-di-scope +public sealed class BlazorServiceAccessor : IBlazorServiceAccessor +{ + private static readonly AsyncLocal CurrentServiceHolder = new(); + + /// + /// Gets or sets the current IServiceProvider. + /// + public IServiceProvider Services + { + get => CurrentServiceHolder.Value!.Services!; + set + { + if (CurrentServiceHolder.Value is { } holder) + { + // Clear the current IServiceProvider trapped in the AsyncLocal. + holder.Services = null; + } + + // Use object indirection to hold the IServiceProvider in an AsyncLocal + // so it can be cleared in all ExecutionContexts when it's cleared. + CurrentServiceHolder.Value = new() { Services = value }; + } + } + + private sealed class BlazorServiceHolder + { + public IServiceProvider? Services { get; set; } + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultAppBarService.cs b/src/framework/Elsa.Studio.Core/Services/DefaultAppBarService.cs new file mode 100644 index 0000000..1881bc0 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultAppBarService.cs @@ -0,0 +1,20 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Services; + +public class DefaultAppBarService : IAppBarService +{ + private readonly ICollection _appBarItems = new List(); + private int _appBarSequence; + + public event Action? AppBarItemsChanged; + public IEnumerable AppBarItems => _appBarItems.ToList(); + + public void AddAppBarItem() where T : IComponent + { + _appBarItems.Add(builder => builder.CreateComponent(ref _appBarSequence)); + AppBarItemsChanged?.Invoke(); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultBackendApiClientProvider.cs b/src/framework/Elsa.Studio.Core/Services/DefaultBackendApiClientProvider.cs new file mode 100644 index 0000000..dc91bf6 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultBackendApiClientProvider.cs @@ -0,0 +1,24 @@ +using System.Reflection; +using Elsa.Api.Client.Extensions; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// +/// Provides API clients to the remote backend. +/// +public class DefaultBackendApiClientProvider(IRemoteBackendAccessor remoteBackendAccessor, IBlazorServiceAccessor blazorServiceAccessor, IServiceProvider serviceProvider) : IBackendApiClientProvider +{ + /// + public Uri Url => remoteBackendAccessor.RemoteBackend.Url; + + /// + public ValueTask GetApiAsync(CancellationToken cancellationToken) where T : class + { + var backendUrl = remoteBackendAccessor.RemoteBackend.Url; + var client = serviceProvider.CreateApi(backendUrl); + var decorator = DispatchProxy.Create>(); + (decorator as BlazorScopedProxyApi)!.Initialize(client, blazorServiceAccessor, serviceProvider); + return new(decorator); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultFeatureService.cs b/src/framework/Elsa.Studio.Core/Services/DefaultFeatureService.cs new file mode 100644 index 0000000..64d5481 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultFeatureService.cs @@ -0,0 +1,59 @@ +using System.Reflection; +using Elsa.Studio.Attributes; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// +public class DefaultFeatureService : IFeatureService +{ + private readonly IEnumerable _features; + private readonly IRemoteFeatureProvider _remoteFeatureProvider; + + /// + /// Initializes a new instance of the class. + /// + public DefaultFeatureService(IEnumerable features, IRemoteFeatureProvider remoteFeatureProvider) + { + _features = features; + _remoteFeatureProvider = remoteFeatureProvider; + } + + /// + public event Action? Initialized; + + /// + public IEnumerable GetFeatures() + { + return _features.ToList(); + } + + /// + public async Task InitializeFeaturesAsync(CancellationToken cancellationToken = default) + { + var remoteFeatures = (await _remoteFeatureProvider.ListAsync(cancellationToken)).ToList(); + + foreach (var feature in GetFeatures()) + { + var remoteFeatureName = feature.GetType().GetCustomAttribute()?.Name; + + if (!string.IsNullOrWhiteSpace(remoteFeatureName)) + { + // Check if the remote feature is enabled. + var remoteFeatureIsEnabled = remoteFeatures.Any(x => x.FullName == remoteFeatureName); + + if (!remoteFeatureIsEnabled) + continue; + } + + await feature.InitializeAsync(cancellationToken); + } + + OnInitialized(); + } + + private void OnInitialized() + { + Initialized?.Invoke(); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultMediator.cs b/src/framework/Elsa.Studio.Core/Services/DefaultMediator.cs new file mode 100644 index 0000000..64c9980 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultMediator.cs @@ -0,0 +1,53 @@ +using Elsa.Studio.Contracts; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Services; + +/// +/// A default implementation of . +/// +public class DefaultMediator : IMediator +{ + private readonly IServiceProvider _serviceProvider; + private readonly ISet _handlers = new HashSet(); + + /// + /// Initializes a new instance of the class. + /// + public DefaultMediator(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + /// + public void Subscribe(THandler handler) where TNotification : INotification where THandler : INotificationHandler + { + _handlers.Add(handler); + } + + /// + public void Unsubscribe(THandler handler) where TNotification : INotification where THandler : INotificationHandler + { + _handlers.Remove(handler); + } + + /// + public void Unsubscribe(INotificationHandler handler) + { + var handlers =_handlers.Where(x => x == handler).ToList(); + + foreach (var h in handlers) + _handlers.Remove(h); + } + + /// + public Task NotifyAsync(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification + { + // Collect handlers registered manually, and handlers registered via DI. + var manualHandlers = _handlers.OfType>().ToList(); + var registeredHandlers = _serviceProvider.GetServices().OfType>().ToList(); + var handlers = manualHandlers.Concat(registeredHandlers).ToList(); + var tasks = handlers.Select(x => x.HandleAsync(notification, cancellationToken)); + return Task.WhenAll(tasks); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultMenuGroupProvider.cs b/src/framework/Elsa.Studio.Core/Services/DefaultMenuGroupProvider.cs new file mode 100644 index 0000000..d05bde0 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultMenuGroupProvider.cs @@ -0,0 +1,18 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; + +namespace Elsa.Studio.Services; + +public class DefaultMenuGroupProvider : IMenuGroupProvider +{ + public ValueTask> GetMenuGroupsAsync(CancellationToken cancellationToken = default) + { + var groups = new List + { + MenuItemGroups.General, + MenuItemGroups.Settings + }; + + return new(groups); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultMenuService.cs b/src/framework/Elsa.Studio.Core/Services/DefaultMenuService.cs new file mode 100644 index 0000000..8733927 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultMenuService.cs @@ -0,0 +1,48 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; + +namespace Elsa.Studio.Services; + +/// +public class DefaultMenuService : IMenuService +{ + private readonly IEnumerable _menuProviders; + private readonly IEnumerable _menuGroupProviders; + + /// + /// Initializes a new instance of the class. + /// + public DefaultMenuService(IEnumerable menuProviders, IEnumerable menuGroupProviders) + { + _menuProviders = menuProviders; + _menuGroupProviders = menuGroupProviders; + } + + /// + public async ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default) + { + var menu = new List(); + + foreach (var menuProvider in _menuProviders) + { + var menuItems = await menuProvider.GetMenuItemsAsync(cancellationToken); + menu.AddRange(menuItems); + } + + return menu.OrderBy(x => x.Order).ToList(); + } + + /// + public async ValueTask> GetMenuItemGroupsAsync(CancellationToken cancellationToken = default) + { + var groups = new List(); + + foreach (var menuGroupProvider in _menuGroupProviders) + { + var menuGroups = await menuGroupProvider.GetMenuGroupsAsync(cancellationToken); + groups.AddRange(menuGroups); + } + + return groups.DistinctBy(x => x.Name).OrderBy(x => x.Order).ToList(); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultRemoteBackendAccessor.cs b/src/framework/Elsa.Studio.Core/Services/DefaultRemoteBackendAccessor.cs new file mode 100644 index 0000000..70600f5 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultRemoteBackendAccessor.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.Options; +using Microsoft.Extensions.Options; + +namespace Elsa.Studio.Services; + +/// +/// A default implementation of that uses the to determine the URL of the remote backend. +/// +public class DefaultRemoteBackendAccessor : IRemoteBackendAccessor +{ + private readonly IOptions _options; + + /// + /// Initializes a new instance of the class. + /// + public DefaultRemoteBackendAccessor(IOptions options) + { + _options = options; + } + + /// + public RemoteBackend RemoteBackend => new(_options.Value.Url); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultStartupTaskRunner.cs b/src/framework/Elsa.Studio.Core/Services/DefaultStartupTaskRunner.cs new file mode 100644 index 0000000..b0766ed --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultStartupTaskRunner.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// +public class DefaultStartupTaskRunner : IStartupTaskRunner +{ + private readonly IEnumerable _startupTasks; + + /// + /// + /// + /// + public DefaultStartupTaskRunner(IEnumerable startupTasks) + { + _startupTasks = startupTasks; + } + + /// + public async Task RunStartupTasksAsync(CancellationToken cancellationToken = default) + { + foreach (var task in _startupTasks) + await task.ExecuteAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultSyntaxService.cs b/src/framework/Elsa.Studio.Core/Services/DefaultSyntaxService.cs new file mode 100644 index 0000000..433c0cd --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultSyntaxService.cs @@ -0,0 +1,38 @@ +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// +public class DefaultExpressionService : IExpressionService +{ + private readonly IExpressionProvider _expressionProvider; + private ICollection _descriptors = default!; + + /// + /// Initializes a new instance of the class. + /// + public DefaultExpressionService(IExpressionProvider expressionProvider) + { + _expressionProvider = expressionProvider; + } + + /// + public async Task> ListDescriptorsAsync(CancellationToken cancellationToken = default) + { + if (_descriptors == null!) + { + var descriptors = await _expressionProvider.ListAsync(cancellationToken); + _descriptors = descriptors.ToList(); + } + + return _descriptors; + } + + /// + public async Task GetByTypeAsync(string type, CancellationToken cancellationToken = default) + { + var descriptors = await ListDescriptorsAsync(cancellationToken); + return descriptors.FirstOrDefault(x => x.Type == type); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultThemeService.cs b/src/framework/Elsa.Studio.Core/Services/DefaultThemeService.cs new file mode 100644 index 0000000..03b413f --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultThemeService.cs @@ -0,0 +1,70 @@ +using Elsa.Studio.Contracts; +using MudBlazor; +using MudBlazor.Utilities; + +namespace Elsa.Studio.Services; + +/// +public class DefaultThemeService : IThemeService +{ + private MudTheme _currentTheme = CreateDefaultTheme(); + private bool _isDarkMode; + + /// + public event Action? CurrentThemeChanged; + + /// + public event Action? IsDarkModeChanged; + + /// + public MudTheme CurrentTheme + { + get => _currentTheme; + set + { + _currentTheme = value; + CurrentThemeChanged?.Invoke(); + } + } + + /// + public bool IsDarkMode + { + get => _isDarkMode; + set + { + _isDarkMode = value; + IsDarkModeChanged?.Invoke(); + } + } + + private static MudTheme CreateDefaultTheme() + { + var theme = new MudTheme + { + LayoutProperties = + { + DefaultBorderRadius = "4px", + }, + PaletteLight = + { + Primary = new("0ea5e9"), + DrawerBackground = new("#f8fafc"), + AppbarBackground = new("#0ea5e9"), + AppbarText = new("#ffffff"), + Background = new("#ffffff"), + Surface = new("#f8fafc") + }, + PaletteDark = + { + Primary = new("0ea5e9"), + AppbarBackground = new("#0f172a"), + DrawerBackground = new("#0f172a"), + Background = new("#0f172a"), + Surface = new("#182234"), + } + }; + + return theme; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultUIFieldExtensionService.cs b/src/framework/Elsa.Studio.Core/Services/DefaultUIFieldExtensionService.cs new file mode 100644 index 0000000..e321a83 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultUIFieldExtensionService.cs @@ -0,0 +1,27 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; + +namespace Elsa.Studio.Services; + +/// +/// Provides a default implementation of UI field extension services. +/// +/// +public class DefaultUIFieldExtensionService(IEnumerable handlers) : IUIFieldExtensionService +{ + /// + /// + /// + public List? TryGetHandlers(string componentName, DisplayInputEditorContext context) + { + var activityName = context.ActivityDescriptor.Name; + var syntax = context.InputDescriptor.DefaultSyntax ?? string.Empty; + var matchingHandlers = handlers + .Where(x => x.GetExtensionForInputComponent(componentName) + && (!x.ActivityTypes.Any() || x.ActivityTypes.Contains(activityName)) + && (!x.Syntaxes.Any() || x.Syntaxes.Contains(syntax))) + .OrderBy(x => x.DisplayOrder) + .ToList(); + return matchingHandlers; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultUIHintService.cs b/src/framework/Elsa.Studio.Core/Services/DefaultUIHintService.cs new file mode 100644 index 0000000..f3a071d --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultUIHintService.cs @@ -0,0 +1,35 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +public class DefaultUIHintService(IEnumerable handlers) : IUIHintService +{ + public IUIHintHandler GetHandler(string uiHint) + { + var handler = handlers.FirstOrDefault(x => x.GetSupportsUIHint(uiHint)); + return handler ?? new UnsupportedUIHintHandler(); + } + + // public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + // { + // var handler = _handlers.FirstOrDefault(x => x.GetSupportsUIHint(context.InputDescriptor.UIHint)); + // return handler == null ? DisplayUnsupportedUIHint(context) : handler.DisplayInputEditor(context); + // } + + // private RenderFragment DisplayUnsupportedUIHint(DisplayInputEditorContext context) + // { + // return builder => + // { + // builder.OpenComponent(0); + // builder.AddAttribute(1, nameof(MudAlert.Severity), Severity.Warning); + // builder.AddAttribute(2, nameof(MudAlert.Class), "my-2"); + // builder.AddAttribute(3, nameof(MudText.ChildContent), (RenderFragment)(textBuilder => + // { + // textBuilder.AddContent(0, $"Unsupported UI hint: {context.InputDescriptor.UIHint}"); + // })); + // builder.CloseElement(); + // }; + // } + + +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/DefaultWidgetRegistry.cs b/src/framework/Elsa.Studio.Core/Services/DefaultWidgetRegistry.cs new file mode 100644 index 0000000..d67f35c --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/DefaultWidgetRegistry.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// +public class DefaultWidgetRegistry : IWidgetRegistry +{ + private HashSet Widgets { get; set; } = new(); + + /// + /// Initializes a new instance of the class. + /// + public DefaultWidgetRegistry(IEnumerable widgets) + { + foreach (var widget in widgets) Add(widget); + } + + /// + public void Add(IWidget widget) + { + Widgets.Add(widget); + } + + /// + public IEnumerable List(string zone) + { + return Widgets.Where(x => x.Zone == zone).OrderBy(x => x.Order); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/EmptyServerInformationProvider.cs b/src/framework/Elsa.Studio.Core/Services/EmptyServerInformationProvider.cs new file mode 100644 index 0000000..9dfb9ad --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/EmptyServerInformationProvider.cs @@ -0,0 +1,16 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; + +namespace Elsa.Studio.Services; + +/// +/// A default implementation of that returns dummy data. +/// +public class EmptyServerInformationProvider : IServerInformationProvider +{ + /// + public ValueTask GetInfoAsync(CancellationToken cancellationToken = default) + { + return new (new ServerInformation("0.0.0")); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/RemoteExpressionProvider.cs b/src/framework/Elsa.Studio.Core/Services/RemoteExpressionProvider.cs new file mode 100644 index 0000000..04e6335 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/RemoteExpressionProvider.cs @@ -0,0 +1,29 @@ +using Elsa.Api.Client.Resources.Scripting.Contracts; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// +/// Provides available expression descriptors from a remote API. +/// +public class RemoteExpressionProvider : IExpressionProvider +{ + private readonly IBackendApiClientProvider _backendApiClientProvider; + + /// + /// Initializes a new instance of the class. + /// + public RemoteExpressionProvider(IBackendApiClientProvider backendApiClientProvider) + { + _backendApiClientProvider = backendApiClientProvider; + } + + /// + public async ValueTask> ListAsync(CancellationToken cancellationToken = default) + { + var api = await _backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(cancellationToken); + return response.Items; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/RemoteFeatureProvider.cs b/src/framework/Elsa.Studio.Core/Services/RemoteFeatureProvider.cs new file mode 100644 index 0000000..3b4e4da --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/RemoteFeatureProvider.cs @@ -0,0 +1,37 @@ +using System.Net; +using Elsa.Api.Client.Resources.Features.Contracts; +using Elsa.Api.Client.Resources.Features.Models; +using Elsa.Studio.Contracts; +using Refit; + +namespace Elsa.Studio.Services; + +/// +/// A feature service that uses a remote backend to retrieve feature flags. +/// +public class RemoteFeatureProvider(IBackendApiClientProvider remoteBackendApiClientProvider) : IRemoteFeatureProvider +{ + /// + public async Task IsEnabledAsync(string featureName, CancellationToken cancellationToken = default) + { + var api = await remoteBackendApiClientProvider.GetApiAsync(cancellationToken); + + try + { + _ = await api.GetAsync(featureName, cancellationToken); + return true; + } + catch (ApiException e) when(e.StatusCode == HttpStatusCode.NotFound) + { + return false; + } + } + + /// + public async Task> ListAsync(CancellationToken cancellationToken = default) + { + var api = await remoteBackendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(cancellationToken); + return response.Items; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/StaticClientInformationProvider.cs b/src/framework/Elsa.Studio.Core/Services/StaticClientInformationProvider.cs new file mode 100644 index 0000000..6e3c59f --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/StaticClientInformationProvider.cs @@ -0,0 +1,17 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; + +namespace Elsa.Studio.Services; + +/// +/// +/// +public class StaticClientInformationProvider : IClientInformationProvider +{ + /// + public ValueTask GetInfoAsync(CancellationToken cancellationToken = default) + { + var version = ToolVersion.Version.ToString(); + return new(new ClientInformation(version)); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/Services/UnsupportedUIHintHandler.cs b/src/framework/Elsa.Studio.Core/Services/UnsupportedUIHintHandler.cs new file mode 100644 index 0000000..a190c2a --- /dev/null +++ b/src/framework/Elsa.Studio.Core/Services/UnsupportedUIHintHandler.cs @@ -0,0 +1,31 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Services; + +/// +/// A fallback UI handler that is used when no other handler is found for a given UI hint. +/// +public class UnsupportedUIHintHandler : IUIHintHandler +{ + public bool GetSupportsUIHint(string uiHint) => false; + + public string UISyntax => "Unsupported"; + + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, nameof(MudAlert.Severity), Severity.Warning); + builder.AddAttribute(2, nameof(MudAlert.Class), "my-2"); + builder.AddAttribute(3, nameof(MudText.ChildContent), (RenderFragment)(textBuilder => + { + textBuilder.AddContent(0, $"Unsupported UI hint: {context.InputDescriptor.UIHint}"); + })); + builder.CloseElement(); + }; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/TokenNames.cs b/src/framework/Elsa.Studio.Core/TokenNames.cs new file mode 100644 index 0000000..fe66282 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/TokenNames.cs @@ -0,0 +1,8 @@ +namespace Elsa.Studio; + +public static class TokenNames +{ + public const string AccessToken = "accessToken"; + public const string IdToken = "idToken"; + public const string RefreshToken = "refreshToken"; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Core/ToolVersion.cs b/src/framework/Elsa.Studio.Core/ToolVersion.cs new file mode 100644 index 0000000..9c04976 --- /dev/null +++ b/src/framework/Elsa.Studio.Core/ToolVersion.cs @@ -0,0 +1,18 @@ +namespace Elsa.Studio; + +/// +/// Represents the version of the tool. +/// +public static class ToolVersion +{ + /// + /// The version of the tool. + /// + public static readonly Version Version = new(3, 5, 0, 0); + + /// + /// Gets the display version of the tool. + /// + /// + public static string GetDisplayVersion() => Version.ToString(2); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/package.json b/src/framework/Elsa.Studio.DomInterop/ClientLib/package.json new file mode 100644 index 0000000..176de95 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/package.json @@ -0,0 +1,19 @@ +{ + "name": "elsa-studio-dom-interop", + "description": "Bundle DOM interop functions.", + "repository": "https://github.com/elsa-workflows/elsa-dashboard", + "license": "MIT", + "version": "1.0.0", + "dependencies": { + + }, + "devDependencies": { + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "typescript": "^5.3.3", + "ts-loader": "^9.5.1" + }, + "scripts": { + "build": "webpack" + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard.ts new file mode 100644 index 0000000..1a6ae49 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard.ts @@ -0,0 +1 @@ +export * from "./clipboard/"; \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard/copy-text.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard/copy-text.ts new file mode 100644 index 0000000..6a667f3 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard/copy-text.ts @@ -0,0 +1,7 @@ +export const copyText = async function (text) { + await navigator.clipboard + .writeText(text) + .catch(function (error) { + alert(error); + }); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard/index.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard/index.ts new file mode 100644 index 0000000..6f79720 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/clipboard/index.ts @@ -0,0 +1 @@ +export * from './copy-text'; \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom.ts new file mode 100644 index 0000000..aa3f7df --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom.ts @@ -0,0 +1 @@ +export * from "./dom/"; \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/click-element.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/click-element.ts new file mode 100644 index 0000000..a08e054 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/click-element.ts @@ -0,0 +1,7 @@ +import {getElement} from "./get-element"; + +export function clickElement(elementOrQuerySelector: Element | string) { + const element = getElement(elementOrQuerySelector) as HTMLElement; + + element.click(); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-bounding-client-rect.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-bounding-client-rect.ts new file mode 100644 index 0000000..b379f79 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-bounding-client-rect.ts @@ -0,0 +1,6 @@ +import {getElement} from "./get-element"; + +export function getBoundingClientRect(elementOrQuerySelector: Element | string): DOMRect { + const element = getElement(elementOrQuerySelector); + return element.getBoundingClientRect(); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-element.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-element.ts new file mode 100644 index 0000000..7ad8263 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-element.ts @@ -0,0 +1,3 @@ +export function getElement(elementOrQuerySelector: Element | string): Element { + return typeof elementOrQuerySelector === 'string' ? document.querySelector(elementOrQuerySelector) : elementOrQuerySelector; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-visible-height.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-visible-height.ts new file mode 100644 index 0000000..51a4e2c --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/get-visible-height.ts @@ -0,0 +1,18 @@ +import {getElement} from "./get-element"; + +export function getVisibleHeight(elementOrQuerySelector: Element | string): number { + const element = getElement(elementOrQuerySelector); + + if(!element) + return 0; + + const rect = element.getBoundingClientRect(); + const windowHeight = window.innerHeight; + + if (rect.bottom > windowHeight) { + const visibleHeight = windowHeight - rect.top; + return visibleHeight > 0 ? visibleHeight : 0; + } + + return rect.height; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/index.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/index.ts new file mode 100644 index 0000000..f803a88 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/element/index.ts @@ -0,0 +1,5 @@ +export * from './click-element'; +export * from './get-bounding-client-rect'; +export * from './get-element'; +export * from './get-visible-height'; + diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/index.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/index.ts new file mode 100644 index 0000000..e72854e --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/dom/index.ts @@ -0,0 +1 @@ +export * from './element'; \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files.ts new file mode 100644 index 0000000..8c5d833 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files.ts @@ -0,0 +1 @@ +export * from "./files/"; \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files/download-file-from-stream.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files/download-file-from-stream.ts new file mode 100644 index 0000000..fbbf17a --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files/download-file-from-stream.ts @@ -0,0 +1,11 @@ +export const downloadFileFromStream = async (fileName, contentStreamReference) => { + const arrayBuffer = await contentStreamReference.arrayBuffer(); + const blob = new Blob([arrayBuffer]); + const url = URL.createObjectURL(blob); + const anchorElement = document.createElement('a'); + anchorElement.href = url; + anchorElement.download = fileName ?? ''; + anchorElement.click(); + anchorElement.remove(); + URL.revokeObjectURL(url); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files/index.ts b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files/index.ts new file mode 100644 index 0000000..b6db309 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/src/files/index.ts @@ -0,0 +1 @@ +export * from './download-file-from-stream'; \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/tsconfig.json b/src/framework/Elsa.Studio.DomInterop/ClientLib/tsconfig.json new file mode 100644 index 0000000..5b77e76 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "outDir": "../wwwroot", + "sourceMap": true, + "noImplicitAny": false, + "module": "ES2022", + "target": "ES2022", + "jsx": "react", + "allowJs": true, + "moduleResolution": "node" + }, + "include": [ + "./src/**/*" + ] +} diff --git a/src/framework/Elsa.Studio.DomInterop/ClientLib/webpack.config.js b/src/framework/Elsa.Studio.DomInterop/ClientLib/webpack.config.js new file mode 100644 index 0000000..0b912cf --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/ClientLib/webpack.config.js @@ -0,0 +1,45 @@ +const path = require('path'); + +module.exports = { + entry: { + dom: './src/dom.ts', + clipboard: './src/clipboard.ts', + files: './src/files.ts', + }, + output: { + filename: '[name].entry.js', + path: path.resolve(__dirname, '..', 'wwwroot'), + library: { + type: "module", + }, + module: true, // Enable outputting ES6 modules. + environment: { + module: true, // The environment supports ES6 modules. + }, + }, + experiments: { + outputModule: true, // This enables the experimental support for outputting ES6 modules + }, + devtool: 'source-map', + mode: 'development', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + { + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }, + { + test: /\.(eot|woff(2)?|ttf|otf|svg)$/i, + type: 'asset' + }, + ] + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, +}; \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Contracts/IClipboard.cs b/src/framework/Elsa.Studio.DomInterop/Contracts/IClipboard.cs new file mode 100644 index 0000000..11a1ad2 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Contracts/IClipboard.cs @@ -0,0 +1,9 @@ +namespace Elsa.Studio.DomInterop.Contracts; + +/// +/// Provides access to the browser's DOM. +/// +public interface IClipboard +{ + Task CopyText(string text, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Contracts/IDomAccessor.cs b/src/framework/Elsa.Studio.DomInterop/Contracts/IDomAccessor.cs new file mode 100644 index 0000000..33c77cc --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Contracts/IDomAccessor.cs @@ -0,0 +1,13 @@ +using Elsa.Studio.DomInterop.Models; + +namespace Elsa.Studio.DomInterop.Contracts; + +/// +/// Provides access to the browser's DOM. +/// +public interface IDomAccessor +{ + Task GetBoundingClientRectAsync(ElementRef elementRef, CancellationToken cancellationToken = default); + Task GetVisibleHeightAsync(ElementRef elementRef, CancellationToken cancellationToken = default); + Task ClickElementAsync(ElementRef elementRef, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Contracts/IFiles.cs b/src/framework/Elsa.Studio.DomInterop/Contracts/IFiles.cs new file mode 100644 index 0000000..e3ceeb2 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Contracts/IFiles.cs @@ -0,0 +1,14 @@ +namespace Elsa.Studio.DomInterop.Contracts; + +/// +/// Provides JS interop methods for the files module. +/// +public interface IFiles +{ + /// + /// Downloads a file from a stream. + /// + /// The name of the file. + /// The stream to download from. + Task DownloadFileFromStreamAsync(string fileName, Stream stream); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Elsa.Studio.DomInterop.csproj b/src/framework/Elsa.Studio.DomInterop/Elsa.Studio.DomInterop.csproj new file mode 100644 index 0000000..d7f377d --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Elsa.Studio.DomInterop.csproj @@ -0,0 +1,28 @@ + + + + Elsa Studio DOM interop services. + elsa studio framework + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/framework/Elsa.Studio.DomInterop/Extensions/ServiceCollectionExtensions.cs b/src/framework/Elsa.Studio.DomInterop/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..4918f51 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,30 @@ +using Elsa.Studio.DomInterop.Contracts; +using Elsa.Studio.DomInterop.Interop; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Elsa.Studio.DomInterop.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddDomInterop(this IServiceCollection services) + { + services.TryAddScoped(); + + return services; + } + + public static IServiceCollection AddClipboardInterop(this IServiceCollection services) + { + services.TryAddScoped(); + + return services; + } + + public static IServiceCollection AddDownloadInterop(this IServiceCollection services) + { + services.TryAddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/FodyWeavers.xml b/src/framework/Elsa.Studio.DomInterop/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/FodyWeavers.xsd b/src/framework/Elsa.Studio.DomInterop/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Interop/ClipboardJsInterop.cs b/src/framework/Elsa.Studio.DomInterop/Interop/ClipboardJsInterop.cs new file mode 100644 index 0000000..8fd604a --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Interop/ClipboardJsInterop.cs @@ -0,0 +1,17 @@ +using Elsa.Studio.DomInterop.Contracts; +using Microsoft.JSInterop; + +namespace Elsa.Studio.DomInterop.Interop; + +/// +/// Provides access to the dom JavaScript module. +/// +public class ClipboardJsInterop(IJSRuntime jsRuntime) : JsInteropBase(jsRuntime), IClipboard +{ + protected override string ModuleName => "clipboard"; + + public async Task CopyText(string text, CancellationToken cancellationToken = default) + { + await InvokeAsync(async module => await module.InvokeVoidAsync("copyText", cancellationToken, text)); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Interop/DomJsInterop.cs b/src/framework/Elsa.Studio.DomInterop/Interop/DomJsInterop.cs new file mode 100644 index 0000000..fd9acdd --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Interop/DomJsInterop.cs @@ -0,0 +1,17 @@ +using Elsa.Studio.DomInterop.Contracts; +using Elsa.Studio.DomInterop.Models; +using Microsoft.JSInterop; + +namespace Elsa.Studio.DomInterop.Interop; + +/// +/// Provides access to the dom JavaScript module. +/// +public class DomJsInterop(IJSRuntime jsRuntime) : JsInteropBase(jsRuntime), IDomAccessor +{ + protected override string ModuleName => "dom"; + + public async Task GetBoundingClientRectAsync(ElementRef element, CancellationToken cancellationToken = default) => await InvokeAsync(async module => await module.InvokeAsync("getBoundingClientRect", cancellationToken, element.Match())); + public async Task GetVisibleHeightAsync(ElementRef elementRef, CancellationToken cancellationToken = default) => await InvokeAsync(async module => await module.InvokeAsync("getVisibleHeight", cancellationToken, elementRef.Match())); + public async Task ClickElementAsync(ElementRef elementRef, CancellationToken cancellationToken = default) => await InvokeAsync(async module => await module.InvokeVoidAsync("clickElement", cancellationToken, elementRef.Match())); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Interop/FilesJsInterop.cs b/src/framework/Elsa.Studio.DomInterop/Interop/FilesJsInterop.cs new file mode 100644 index 0000000..d3fec00 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Interop/FilesJsInterop.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.DomInterop.Contracts; +using Microsoft.JSInterop; + +namespace Elsa.Studio.DomInterop.Interop; + +/// +/// Provides JS interop methods for the files module. +/// +public class FilesJsInterop : JsInteropBase, IFiles +{ + /// + public FilesJsInterop(IJSRuntime jsRuntime) : base(jsRuntime) + { + } + + /// + protected override string ModuleName => "files"; + + /// + public async Task DownloadFileFromStreamAsync(string fileName, Stream stream) + { + var streamRef = new DotNetStreamReference(stream); + await InvokeAsync(async module => await module.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef)); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Interop/JsInteropBase.cs b/src/framework/Elsa.Studio.DomInterop/Interop/JsInteropBase.cs new file mode 100644 index 0000000..3528e72 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Interop/JsInteropBase.cs @@ -0,0 +1,49 @@ +using Microsoft.JSInterop; + +namespace Elsa.Studio.DomInterop.Interop; + +/// +/// Provides access to the designer JavaScript module. +/// +public abstract class JsInteropBase : IAsyncDisposable +{ + private readonly Lazy> _moduleTask; + + protected abstract string ModuleName { get; } + + protected JsInteropBase(IJSRuntime jsRuntime) + { + _moduleTask = new(() => jsRuntime.InvokeAsync( + "import", $"./_content/Elsa.Studio.DomInterop/{ModuleName}.entry.js").AsTask()); + } + + public async ValueTask DisposeAsync() + { + if (_moduleTask.IsValueCreated) + { + var module = await _moduleTask.Value; + + try + { + await module.DisposeAsync(); + } + catch (JSDisconnectedException) + { + // This exception is thrown when the browser window is closed or the page reloads. + // We can safely ignore it. + } + } + } + + protected async Task InvokeAsync(Func func) + { + var module = await _moduleTask.Value; + await func(module); + } + + protected async Task InvokeAsync(Func> func) + { + var module = await _moduleTask.Value; + return await func(module); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Models/DomRect.cs b/src/framework/Elsa.Studio.DomInterop/Models/DomRect.cs new file mode 100644 index 0000000..92cf08d --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Models/DomRect.cs @@ -0,0 +1,13 @@ +namespace Elsa.Studio.DomInterop.Models; + +public struct DomRect +{ + public double X { get; set; } + public double Y { get; set; } + public double Width { get; set; } + public double Height { get; set; } + public double Top { get; set; } + public double Right { get; set; } + public double Bottom { get; set; } + public double Left { get; set; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Models/ElementRef.cs b/src/framework/Elsa.Studio.DomInterop/Models/ElementRef.cs new file mode 100644 index 0000000..1905b46 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Models/ElementRef.cs @@ -0,0 +1,12 @@ +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.DomInterop.Models; + +public class ElementRef : Union +{ + private ElementRef(string value) : base(value) { } + private ElementRef(ElementReference value) : base(value) { } + public static implicit operator ElementRef(string value) => new(value); + public static implicit operator ElementRef(ElementReference value) => new(value); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.DomInterop/Models/Union.cs b/src/framework/Elsa.Studio.DomInterop/Models/Union.cs new file mode 100644 index 0000000..3115751 --- /dev/null +++ b/src/framework/Elsa.Studio.DomInterop/Models/Union.cs @@ -0,0 +1,33 @@ +namespace Elsa.Studio.Models; + +public class Union +{ + private readonly T1? _value1; + private readonly T2? _value2; + private readonly bool _isValue1; + + protected Union(T1 value) + { + _value1 = value; + _isValue1 = true; + } + + protected Union(T2 value) + { + _value2 = value; + _isValue1 = false; + } + + public static implicit operator Union(T1 value) => new(value); + public static implicit operator Union(T2 value) => new(value); + + public T Match(Func case1, Func case2) + { + if (case1 == null) throw new ArgumentNullException(nameof(case1)); + if (case2 == null) throw new ArgumentNullException(nameof(case2)); + + return _isValue1 ? case1(_value1!) : case2(_value2!); + } + + public object Match() => _isValue1 ? _value1! : _value2!; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Branding/DefaultBrandingProvider.cs b/src/framework/Elsa.Studio.Shared/Branding/DefaultBrandingProvider.cs new file mode 100644 index 0000000..0029328 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Branding/DefaultBrandingProvider.cs @@ -0,0 +1,33 @@ +using Elsa.Studio.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Branding; + +/// +/// Provides default branding information for the application, including the application name, logo URL, and reverse logo URL. +/// Implements the interface. +/// +public class DefaultBrandingProvider : IBrandingProvider +{ + /// + public virtual string AppName => $"Elsa {ToolVersion.GetDisplayVersion()}"; + + /// + public virtual string LogoUrl => GetLogoUrl(false); + + /// + public virtual string LogoReverseUrl => GetLogoUrl(true); + + private string GetLogoUrl(bool v) + { + return "_content/Elsa.Studio.Shell/img/icon.png"; + } + + public virtual RenderFragment Branding => + builder => + { + builder.OpenComponent(0, typeof(DefaultBranding)); + builder.AddAttribute(1, "Provider", this); + builder.CloseComponent(); + }; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Branding/IBrandingProvider.cs b/src/framework/Elsa.Studio.Shared/Branding/IBrandingProvider.cs new file mode 100644 index 0000000..9478347 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Branding/IBrandingProvider.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Branding; + +/// +/// Provides branding information for an application, including its name, logo, and reverse logo. +/// +public interface IBrandingProvider +{ + /// + /// The name of the application. + /// + [Obsolete("Use Branding instead to provide a custom component, or configure the DefaultBrandingProvider with an AppName.")] string AppName { get; } + + /// + /// Logo on a white background. + /// + [Obsolete("Use Branding instead to provide a custom component, or configure the DefaultBrandingProvider with a LogoUrl.")] string? LogoUrl { get; } + + /// + /// Logo on a dark background + /// + [Obsolete("Use Branding instead to provide a custom component, or configure the DefaultBrandingProvider with a LogoReverseUrl.")] string? LogoReverseUrl { get; } + + /// + /// The component to render. Use this to completely customize the branding component. + /// + RenderFragment Branding { get; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/ClientPackageVersion.razor b/src/framework/Elsa.Studio.Shared/Components/ClientPackageVersion.razor new file mode 100644 index 0000000..e15367b --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/ClientPackageVersion.razor @@ -0,0 +1,16 @@ +@using Elsa.Studio.Contracts + +Client version: @PackageVersion + +@code { + [Inject] private IClientInformationProvider ClientInformationProvider { get; set; } = default!; + private string PackageVersion { get; set; } = "Loading..."; + + /// + protected override async Task OnInitializedAsync() + { + var info = await ClientInformationProvider.GetInfoAsync(); + PackageVersion = info.PackageVersion; + } + +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/DataPanel.razor b/src/framework/Elsa.Studio.Shared/Components/DataPanel.razor new file mode 100644 index 0000000..6761c81 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/DataPanel.razor @@ -0,0 +1,88 @@ +@using Elsa.Studio.DomInterop.Contracts +@using Elsa.Studio.Localization.Time.Components +@using Elsa.Studio.Models + + + + @{ + var data = HideEmptyValues + ? Data.Where(x => !string.IsNullOrWhiteSpace(x.Text)).ToList() + : Data; + } + @if (data.Any()) + { + @foreach (var item in data) + { + + @item.Label + + + + + @if (!string.IsNullOrWhiteSpace(item.Link)) + { + @item.Text + } + else if (item.OnClick != null) + { + @item.Text + } + else + { + @if (item.Label == "Created" || item.Label == "Updated" || item.Label == "Finished") + { + + } + else + { + @item.Text + } + } + + + } + } + else + { + if (ShowNoDataAlert) + { + @NoDataMessage + } + } + + + +@code { + + /// + /// The data to display. + /// + [Parameter] + public DataPanelModel Data { get; set; } = new (); + + /// + /// If true, empty values will be hidden. + /// + [Parameter] + public bool HideEmptyValues { get; set; } + + /// + /// If true, a message will be displayed when there is no data. + /// + [Parameter] + public bool ShowNoDataAlert { get; set; } + + /// + /// The message to display when there is no data. + /// + [Parameter] + public string NoDataMessage { get; set; } = "No data available."; + + [Inject] private IClipboard Clipboard { get; set; } = null!; + + private async Task OnCopyClicked(string value) + { + await Clipboard.CopyText(value); + } + +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/DefaultBranding.razor b/src/framework/Elsa.Studio.Shared/Components/DefaultBranding.razor new file mode 100644 index 0000000..4a6b393 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/DefaultBranding.razor @@ -0,0 +1,13 @@ +@using Elsa.Studio.Branding + + +
+ + @Provider.AppName +
+
+ +@code{ + [Parameter] public IBrandingProvider Provider { get; set; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/ExpressionEditor.razor b/src/framework/Elsa.Studio.Shared/Components/ExpressionEditor.razor new file mode 100644 index 0000000..d6ac883 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/ExpressionEditor.razor @@ -0,0 +1,56 @@ +@using Elsa.Api.Client.Resources.Scripting.Extensions; +@using Elsa.Api.Client.Resources.Scripting.Models; +@using Variant = MudBlazor.Variant + +
+
+ + + + + + @if (!DisplayCodeEditor) + { + @ChildContent + } + +
+ @{ + + RenderFragment DisplayDropdownItem(ExpressionDescriptor? item) => @
+ @{ + var isChecked = item?.Type == _selectedExpressionType; + var iconColor = isChecked ? Color.Secondary : Color.Transparent; + var displayName = item?.DisplayName ?? DefaultOption; + + @displayName + } +
; + +
+ + @DisplayDropdownItem(null) + + @foreach (var item in BrowsableExpressionDescriptors.Where(i => !string.IsNullOrEmpty(i.GetMonacoLanguage()))) + { + @DisplayDropdownItem(item) + } + + @foreach (var item in BrowsableExpressionDescriptors.Skip(1).Where(i => string.IsNullOrEmpty(i.GetMonacoLanguage()))) + { + @DisplayDropdownItem(item) + } + +
+ } +
\ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/ExpressionEditor.razor.cs b/src/framework/Elsa.Studio.Shared/Components/ExpressionEditor.razor.cs new file mode 100644 index 0000000..1eef000 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/ExpressionEditor.razor.cs @@ -0,0 +1,231 @@ +using BlazorMonaco.Editor; +using Elsa.Api.Client.Resources.Scripting.Extensions; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Models; +using Elsa.Studio.Services; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using MudBlazor; +using ThrottleDebounce; + +namespace Elsa.Studio.Components; + +/// +/// A component that renders an input for an expression. +/// +public partial class ExpressionEditor : IDisposable +{ + private readonly string[] _expressionTypeBlacklist = ["Literal", "Object", "Variable"]; + private string? _selectedExpressionType; + private StandaloneCodeEditor? _monacoEditor; + private bool _isInternalContentChange; + private bool _isInitialized; + private string _monacoEditorId = $"monaco-editor-{Guid.NewGuid()}:N"; + private string? _lastMonacoEditorContent; + private RateLimitedFunc _throttledValueChanged; + private ICollection _expressionDescriptors = new List(); + private TaskCompletionSource? _initializationTcs; + + /// + public ExpressionEditor() + { + _throttledValueChanged = Debouncer.Debounce(InvokeValueChangedCallbackAsync, TimeSpan.FromMilliseconds(500)); + } + + /// + /// The content to render inside the editor. + /// + [Parameter] public RenderFragment ChildContent { get; set; } = null!; + + [Parameter] public Expression? Expression { get; set; } = new(string.Empty, string.Empty); + [Parameter] public string DefaultOption { get; set; } = "Default"; + [Parameter] public string DisplayName { get; set; } = string.Empty; + [Parameter] public string Description { get; set; } = string.Empty; + [Parameter] public bool ReadOnly { get; set; } + [Parameter] public IDictionary CustomProperties { get; set; } = new Dictionary(); + [Parameter] public Func? ExpressionChanged { get; set; } + + [Inject] private TypeDefinitionService TypeDefinitionService { get; set; } = null!; + [Inject] private IExpressionService ExpressionService { get; set; } = null!; + [Inject] private IJSRuntime JSRuntime { get; set; } = null!; + [Inject] private IEnumerable MonacoHandlers { get; set; } = null!; + [Inject] private IUIHintService UIHintService { get; set; } = null!; + private IEnumerable BrowsableExpressionDescriptors => _expressionDescriptors.Where(x => x.IsBrowsable); + private ExpressionDescriptor? SelectedExpressionDescriptor => _expressionDescriptors.FirstOrDefault(x => x.Type == _selectedExpressionType); + private string SelectedExpressionTypeDisplayName => SelectedExpressionDescriptor?.DisplayName ?? DefaultOption; + private string MonacoLanguage => SelectedExpressionDescriptor?.GetMonacoLanguage() ?? string.Empty; + private bool DisplayCodeEditor => _selectedExpressionType != null && _selectedExpressionType != DefaultOption; + private bool DisplayModePicker => !DisplayCodeEditor; + private string? ButtonIcon => DisplayModePicker ? Icons.Material.Filled.MoreVert : null; + private string? ButtonLabel => DisplayModePicker ? null : SelectedExpressionTypeDisplayName; + private Variant ButtonVariant => DisplayModePicker ? default : Variant.Filled; + private Color ButtonColor => DisplayModePicker ? default : Color.Primary; + private string? ButtonEndIcon => DisplayModePicker ? null : Icons.Material.Filled.KeyboardArrowDown; + private Color ButtonEndColor => DisplayModePicker ? default : Color.Secondary; + + private string? MonacoSyntax { get; set; } + private bool MonacoSyntaxExist => !string.IsNullOrEmpty(MonacoLanguage); + + /// + /// Updates the internal state of the editor with the provided expression. + /// + /// The expression to update the editor with. Can be null. + public async Task UpdateAsync(Expression? expression) + { + if (!_isInitialized || _monacoEditor == null) + { + _initializationTcs ??= new(); + await _initializationTcs.Task; + } + + await UpdateMonacoEditorAsync(expression); + } + + /// + protected override async Task OnInitializedAsync() + { + var expressionDescriptors = (await ExpressionService.ListDescriptorsAsync()).ExceptBy(_expressionTypeBlacklist, x => x.Type).ToList(); + _selectedExpressionType = expressionDescriptors.First().Type; + _expressionDescriptors = expressionDescriptors.ToList(); + } + + private async Task UpdateMonacoLanguageAsync() + { + if (_monacoEditor == null) + return; + + if (SelectedExpressionDescriptor?.Type == null) + return; + + if (string.IsNullOrWhiteSpace(MonacoLanguage)) + return; + + var model = await _monacoEditor.GetModel(); + await Global.SetModelLanguage(JSRuntime, model, MonacoLanguage); + await RunMonacoHandlersAsync(_monacoEditor); + } + + /// + protected override Task OnParametersSetAsync() + { + _selectedExpressionType = Expression?.Type; + return base.OnParametersSetAsync(); + } + + private StandaloneEditorConstructionOptions ConfigureMonacoEditor(StandaloneCodeEditor editor) + { + return new() + { + Language = MonacoLanguage, + Value = Expression?.Value?.ToString() ?? "", + FontFamily = "Roboto Mono, monospace", + RenderLineHighlight = "none", + FixedOverflowWidgets = true, + Minimap = new() + { + Enabled = false + }, + AutomaticLayout = true, + LineNumbers = "on", + Theme = "vs", + RoundedSelection = true, + ScrollBeyondLastLine = false, + OverviewRulerLanes = 0, + OverviewRulerBorder = false, + LineDecorationsWidth = 0, + HideCursorInOverviewRuler = true, + GlyphMargin = false, + ReadOnly = ReadOnly, + DomReadOnly = ReadOnly + }; + } + + private async Task OnSyntaxSelectedAsync(string? syntax) + { + _selectedExpressionType = syntax; + + var value = Expression?.Value?.ToString() ?? ""; + var expressionType = syntax ?? DefaultOption; + var expression = new Expression(expressionType, value); + await InvokeValueChangedCallbackAsync(expression); + await UpdateMonacoLanguageAsync(); + StateHasChanged(); + } + + private async Task OnMonacoContentChangedAsync(ModelContentChangedEvent e) + { + if (_isInternalContentChange) + return; + + var value = await _monacoEditor!.GetValue(); + + // This event gets fired even when the content hasn't changed, for example, when the containing pane is resized. + // This happens from within the monaco editor itself (or the Blazor wrapper, not sure). + if (value == _lastMonacoEditorContent) + return; + + var expression = new Expression(_selectedExpressionType!, value); + _lastMonacoEditorContent = value; + await ThrottleValueChangedCallbackAsync(expression); + } + + private async Task ThrottleValueChangedCallbackAsync(Expression expression) => await _throttledValueChanged.InvokeAsync(expression); + + private async Task InvokeValueChangedCallbackAsync(Expression? expression) + { + await InvokeAsync(async () => + { + if (ExpressionChanged != null) + await ExpressionChanged.Invoke(expression); + }); + } + + private async Task OnMonacoInitializedAsync() + { + _isInitialized = true; + + if (_initializationTcs != null) + { + _initializationTcs.SetResult(true); + _initializationTcs = null; + return; + } + + await UpdateMonacoEditorAsync(Expression); + } + + private async Task UpdateMonacoEditorAsync(Expression? expression) + { + _isInternalContentChange = true; + var model = await _monacoEditor!.GetModel(); + var expressionText = expression?.Value?.ToString() ?? string.Empty; + + if (expression?.Type != null) + _selectedExpressionType = expression.Type; + + _lastMonacoEditorContent = expressionText; + await model.SetValue(expressionText); + _isInternalContentChange = false; + await Global.SetModelLanguage(JSRuntime, model, MonacoLanguage); + await RunMonacoHandlersAsync(_monacoEditor); + } + + private async Task RunMonacoHandlersAsync(StandaloneCodeEditor editor) + { + if (SelectedExpressionDescriptor == null) + return; + + var context = new MonacoContext(editor, SelectedExpressionDescriptor, CustomProperties); + + foreach (var handler in MonacoHandlers) + await handler.InitializeAsync(context); + } + + /// + public void Dispose() + { + _throttledValueChanged.Dispose(); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/ExpressionInput.razor b/src/framework/Elsa.Studio.Shared/Components/ExpressionInput.razor new file mode 100644 index 0000000..5c83b87 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/ExpressionInput.razor @@ -0,0 +1,54 @@ +@using Elsa.Api.Client.Resources.Scripting.Extensions; +@using Elsa.Api.Client.Resources.Scripting.Models; +@using Elsa.Studio.Enums + +
+
+ + @if (ShowMonacoEditor) + { + + + + + + + + } + else + { + + } + +
+ @if (EditorContext.InputDescriptor.IsWrapped) + { + RenderFragment DisplayContent(ExpressionDescriptor item) => @
+ @{ + var isChecked = item.Type == _selectedExpressionType; + var iconColor = isChecked ? Color.Secondary : Color.Transparent; + + @item.DisplayName + }
; +
+ + @DisplayContent(BrowsableExpressionDescriptors.First()) + + @foreach (var item in BrowsableExpressionDescriptors.Where(i=>!string.IsNullOrEmpty(i.GetMonacoLanguage()))) + { + @DisplayContent(item); + } + + @foreach (var item in BrowsableExpressionDescriptors.Skip(1).Where(i=>string.IsNullOrEmpty(i.GetMonacoLanguage()))) + { + @DisplayContent(item); + } + +
+ } +
\ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/ExpressionInput.razor.cs b/src/framework/Elsa.Studio.Shared/Components/ExpressionInput.razor.cs new file mode 100644 index 0000000..80a6b45 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/ExpressionInput.razor.cs @@ -0,0 +1,244 @@ +using BlazorMonaco.Editor; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.Scripting.Extensions; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Models; +using Elsa.Studio.Services; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using MudBlazor; +using ThrottleDebounce; + +namespace Elsa.Studio.Components; + +/// +/// A component that renders an input for an expression. +/// +public partial class ExpressionInput : IDisposable +{ + private const string DefaultSyntax = "Literal"; + private readonly string[] _uiSyntaxes = ["Literal", "Object"]; + private string _selectedExpressionType = DefaultSyntax; + private string _selectedExpressionTypeDisplayName = DefaultSyntax; + private StandaloneCodeEditor? _monacoEditor = null!; + private bool _isInternalContentChange; + private string _monacoEditorId = $"monaco-editor-{Guid.NewGuid()}:N"; + private string? _lastMonacoEditorContent; + private RateLimitedFunc _throttledValueChanged; + private ICollection _expressionDescriptors = new List(); + + /// + public ExpressionInput() + { + _throttledValueChanged = Debouncer.Debounce(InvokeValueChangedCallbackAsync, TimeSpan.FromMilliseconds(500)); + } + + /// + /// The context for the editor. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + /// + /// The content to render inside the editor. + /// + [Parameter] public RenderFragment ChildContent { get; set; } = null!; + + /// + /// A flag indicating whether the editor should only display code. + /// + [Parameter] public bool IsCodeOnly { get; set; } + + [Inject] private TypeDefinitionService TypeDefinitionService { get; set; } = null!; + [Inject] private IExpressionService ExpressionService { get; set; } = null!; + [Inject] private IJSRuntime JSRuntime { get; set; } = null!; + [Inject] private IEnumerable MonacoHandlers { get; set; } = null!; + [Inject] private IUIHintService UIHintService { get; set; } = null!; + private IEnumerable BrowsableExpressionDescriptors => _expressionDescriptors.Where(x => x.IsBrowsable); + private ExpressionDescriptor? SelectedExpressionDescriptor => _expressionDescriptors.FirstOrDefault(x => x.Type == _selectedExpressionType); + private string MonacoLanguage => SelectedExpressionDescriptor?.GetMonacoLanguage() ?? string.Empty; + private string UISyntax => EditorContext.UIHintHandler.UISyntax; + private string ComponentType => EditorContext.InputDescriptor.UIHint; + private bool IsUISyntax => !IsCodeOnly && _selectedExpressionType == UISyntax; + private string? ButtonIcon => IsUISyntax ? Icons.Material.Filled.MoreVert : null; + private string? ButtonLabel => IsUISyntax ? null : _selectedExpressionTypeDisplayName; + private Variant ButtonVariant => IsUISyntax ? default : Variant.Filled; + private Color ButtonColor => IsUISyntax ? default : Color.Primary; + private string? ButtonEndIcon => IsUISyntax ? null : Icons.Material.Filled.KeyboardArrowDown; + private Color ButtonEndColor => IsUISyntax ? default : Color.Secondary; + private bool ShowMonacoEditor => IsCodeOnly || (!IsUISyntax && EditorContext.InputDescriptor.IsWrapped && MonacoSyntaxExist); + private string DisplayName => EditorContext.InputDescriptor.DisplayName ?? EditorContext.InputDescriptor.Name; + private string? Description => EditorContext.InputDescriptor.Description; + private string InputValue => EditorContext.GetExpressionValueOrDefault(); + + private string? MonacoSyntax { get; set; } + private bool MonacoSyntaxExist => !string.IsNullOrEmpty(MonacoLanguage); + + /// + protected override async Task OnInitializedAsync() + { + var defaultDescriptor = new ExpressionDescriptor(UISyntax, "Default"); + var expressionDescriptors = (await ExpressionService.ListDescriptorsAsync()).ExceptBy(_uiSyntaxes, x => x.Type).ToList(); + + if (IsCodeOnly) + _selectedExpressionType = expressionDescriptors.First().Type; + else + expressionDescriptors = expressionDescriptors.Prepend(defaultDescriptor).ToList(); + + _expressionDescriptors = expressionDescriptors.ToList(); + } + + private async Task UpdateMonacoLanguageAsync() + { + if (_monacoEditor == null) + return; + + var expressionDescriptor = SelectedExpressionDescriptor; + + if (expressionDescriptor == null) + return; + + var monacoLanguage = expressionDescriptor.GetMonacoLanguage(); + _selectedExpressionTypeDisplayName = expressionDescriptor.DisplayName; + + if (string.IsNullOrWhiteSpace(monacoLanguage)) + return; + + var model = await _monacoEditor.GetModel(); + await Global.SetModelLanguage(JSRuntime, model, monacoLanguage); + await RunMonacoHandlersAsync(_monacoEditor); + } + + /// + protected override Task OnParametersSetAsync() + { + var selectedExpressionDescriptor = EditorContext.SelectedExpressionDescriptor; + _selectedExpressionType = selectedExpressionDescriptor?.Type ?? UISyntax; + _selectedExpressionTypeDisplayName = selectedExpressionDescriptor?.DisplayName ?? UISyntax; + + UpdateUIHintAsync(EditorContext); + return base.OnParametersSetAsync(); + } + + private StandaloneEditorConstructionOptions ConfigureMonacoEditor(StandaloneCodeEditor editor) + { + return new() + { + Language = MonacoLanguage, + Value = InputValue, + FontFamily = "Roboto Mono, monospace", + RenderLineHighlight = "none", + FixedOverflowWidgets = true, + Minimap = new() + { + Enabled = false + }, + AutomaticLayout = true, + LineNumbers = "on", + Theme = "vs", + RoundedSelection = true, + ScrollBeyondLastLine = false, + OverviewRulerLanes = 0, + OverviewRulerBorder = false, + LineDecorationsWidth = 0, + HideCursorInOverviewRuler = true, + GlyphMargin = false, + ReadOnly = EditorContext.IsReadOnly, + DomReadOnly = EditorContext.IsReadOnly + }; + } + + private async Task OnMonacoInitializedAsync() + { + _isInternalContentChange = true; + var model = await _monacoEditor!.GetModel(); + _lastMonacoEditorContent = InputValue; + await model.SetValue(InputValue); + _isInternalContentChange = false; + await Global.SetModelLanguage(JSRuntime, model, MonacoLanguage); + await RunMonacoHandlersAsync(_monacoEditor); + } + + private async Task OnSyntaxSelectedAsync(string syntax) + { + _selectedExpressionType = syntax; + + var value = InputValue; + var input = (WrappedInput?)EditorContext.Value ?? new WrappedInput(); + + input.Expression = new(_selectedExpressionType, value); + await InvokeValueChangedCallbackAsync(input); + await UpdateMonacoLanguageAsync(); + } + + /// + /// Used to display the UI hint when the user selects any other choice than a language supported by the monaco editor. + /// + private void UpdateUIHintAsync(DisplayInputEditorContext editorContext) + { + if (_selectedExpressionType == "Variable") + { + var uiHintHandler = UIHintService.GetHandler("variable-picker"); + var editor = uiHintHandler.DisplayInputEditor(editorContext); + ChildContent = editor; + return; + } + + if (MonacoSyntax == null + && _selectedExpressionType == editorContext.SelectedExpressionDescriptor?.Type + && editorContext.SelectedExpressionDescriptor.Properties.TryGetValue("UIHint", out var uiHint)) + { + var uiHintHandler = UIHintService.GetHandler(uiHint); + var editor = uiHintHandler.DisplayInputEditor(editorContext); + _selectedExpressionTypeDisplayName = editorContext.SelectedExpressionDescriptor.DisplayName; + + ChildContent = editor; + } + } + + private async Task OnMonacoContentChangedAsync(ModelContentChangedEvent e) + { + if (_isInternalContentChange) + return; + + var value = await _monacoEditor!.GetValue(); + + // This event gets fired even when the content hasn't changed, but for example when the containing pane is resized. + // This happens from within the monaco editor itself (or the Blazor wrapper, not sure). + if (value == _lastMonacoEditorContent) + return; + + var input = (WrappedInput?)EditorContext.Value ?? new WrappedInput(); + input.Expression = new(_selectedExpressionType, value); + _lastMonacoEditorContent = value; + await ThrottleValueChangedCallbackAsync(input); + } + + private async Task ThrottleValueChangedCallbackAsync(WrappedInput input) => await _throttledValueChanged.InvokeAsync(input); + + private async Task InvokeValueChangedCallbackAsync(WrappedInput input) + { + await InvokeAsync(async () => await EditorContext.OnValueChanged(input)); + } + + private async Task RunMonacoHandlersAsync(StandaloneCodeEditor editor) + { + var customProps = new Dictionary + { + { nameof(ActivityDescriptor), EditorContext.ActivityDescriptor }, + { nameof(PropertyDescriptor), EditorContext.InputDescriptor }, + { "WorkflowDefinitionId", EditorContext.WorkflowDefinition.DefinitionId } + }; + + var expressionDescriptor = SelectedExpressionDescriptor?? new ExpressionDescriptor("Literal", "Default"); + var context = new MonacoContext(editor, expressionDescriptor, customProps); + + foreach (var handler in MonacoHandlers) + await handler.InitializeAsync(context); + } + + /// + void IDisposable.Dispose() => _throttledValueChanged.Dispose(); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/FieldExtension.razor b/src/framework/Elsa.Studio.Shared/Components/FieldExtension.razor new file mode 100644 index 0000000..368d084 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/FieldExtension.razor @@ -0,0 +1,79 @@ +@using Elsa.Studio.Contracts +@using Elsa.Studio.Enums +@using Elsa.Studio.Models + + + +@if (hasExtensions) +{ + + @foreach (var extension in TopExtensions ?? Enumerable.Empty()) + { + @extension.DisplayExtension(EditorContext) + } + @ChildContent + @foreach (var extension in BottomExtensions ?? Enumerable.Empty()) + { + @extension.DisplayExtension(EditorContext) + } + +} +else +{ + @ChildContent +} + + +@code +{ + private bool isHovered = false; + private bool hasExtensions => AllExtensions?.Count != 0; + private List? AllExtensions; + private List? TopExtensions; + private List? BottomExtensions; + + /// + /// The UI Hint component type the extensions should be rendered for. + /// + [Parameter] public string UIHintComponent { get; set; } = default!; + + /// + /// The editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = default!; + + /// + /// The content wrap with extensions. + /// + [Parameter] public RenderFragment ChildContent { get; set; } = default!; + + [Inject] private IUIFieldExtensionService FieldExtensionService { get; set; } + + /// + protected override void OnInitialized() + { + AllExtensions = FieldExtensionService.TryGetHandlers(UIHintComponent, EditorContext); + if (AllExtensions is not null) + { + TopExtensions = AllExtensions.Where(p => p.Position == FieldExtensionPosition.Top).ToList(); + BottomExtensions = AllExtensions.Where(p => p.Position == FieldExtensionPosition.Bottom).ToList(); + } + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/NavMenu.razor b/src/framework/Elsa.Studio.Shared/Components/NavMenu.razor new file mode 100644 index 0000000..eac9192 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/NavMenu.razor @@ -0,0 +1,33 @@ +@using Elsa.Studio.Contracts +@using Elsa.Studio.Models +@inject IMenuService MenuService; + + + @foreach (var menuItemGroup in _menuItemsGroups.Values) + { + var menuItems = _menuItems.Where(x => x.GroupName == menuItemGroup.Name).ToList(); + + @if (menuItems.Any()) + { + @menuItemGroup.Text + + foreach (var menuItem in menuItems) + { + + } + } + } + + +@code +{ + private IDictionary _menuItemsGroups = new Dictionary(); + private IEnumerable _menuItems = new List(); + + /// + protected override async Task OnInitializedAsync() + { + _menuItemsGroups = (await MenuService.GetMenuItemGroupsAsync()).ToDictionary(x => x.Name); + _menuItems = await MenuService.GetMenuItemsAsync(); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/NavMenuItem.razor b/src/framework/Elsa.Studio.Shared/Components/NavMenuItem.razor new file mode 100644 index 0000000..6715ec7 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/NavMenuItem.razor @@ -0,0 +1,20 @@ +@using Elsa.Studio.Models +@if (!MenuItem.SubMenuItems.Any()) +{ + @MenuItem.Text +} +else +{ + + @foreach (var subItem in MenuItem.SubMenuItems) + { + + } + +} + +@code +{ + [Parameter] + public MenuItem MenuItem { get; set; } = default!; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/PageHeading.razor b/src/framework/Elsa.Studio.Shared/Components/PageHeading.razor new file mode 100644 index 0000000..5b71e59 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/PageHeading.razor @@ -0,0 +1,5 @@ +@Text + +@code { + [Parameter] public string Text { get; set; } = "Untitled"; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/ProductInfoDialog.razor b/src/framework/Elsa.Studio.Shared/Components/ProductInfoDialog.razor new file mode 100644 index 0000000..45f4e69 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/ProductInfoDialog.razor @@ -0,0 +1,17 @@ + + + + + + + + + Close + + + +@code { + [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!; + + void Close() => MudDialog.Close(DialogResult.Ok(true)); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/ScrollableWell.razor b/src/framework/Elsa.Studio.Shared/Components/ScrollableWell.razor new file mode 100644 index 0000000..4d8ac15 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/ScrollableWell.razor @@ -0,0 +1,20 @@ +
+
+ @ChildContent +
+
+ +@code +{ + /// + /// The maximum height of the component. + /// + [Parameter] + public int MaxHeight { get; set; } = 300; + + /// + /// The content to be rendered inside the component. + /// + [Parameter] + public RenderFragment? ChildContent { get; set; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/ServerPackageVersion.razor b/src/framework/Elsa.Studio.Shared/Components/ServerPackageVersion.razor new file mode 100644 index 0000000..5e2500f --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/ServerPackageVersion.razor @@ -0,0 +1,16 @@ +@using Elsa.Studio.Contracts +@inherits StudioComponentBase +Server version: @PackageVersion + +@code { + [Inject] private IServerInformationProvider ServerInformationProvider { get; set; } = default!; + private string PackageVersion { get; set; } = "Loading..."; + + /// + protected override async Task OnInitializedAsync() + { + var info = await ServerInformationProvider.GetInfoAsync(); + PackageVersion = info.PackageVersion; + } + +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/StudioComponentBase.cs b/src/framework/Elsa.Studio.Shared/Components/StudioComponentBase.cs new file mode 100644 index 0000000..c314b2d --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/StudioComponentBase.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Services; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Components; + +/// Base class for components. This class sets the property to the instance. +/// See https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-7.0#access-server-side-blazor-services-from-a-different-di-scope +public abstract class StudioComponentBase : ComponentBase; \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/Unauthorized.razor b/src/framework/Elsa.Studio.Shared/Components/Unauthorized.razor new file mode 100644 index 0000000..a5d625c --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/Unauthorized.razor @@ -0,0 +1 @@ +Unauthorized \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/VerticalWell.razor b/src/framework/Elsa.Studio.Shared/Components/VerticalWell.razor new file mode 100644 index 0000000..1cd031f --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/VerticalWell.razor @@ -0,0 +1,16 @@ +
+ @ChildContent +
+ +@code +{ + /// + /// The content to be rendered inside the component. + /// + [Parameter] public RenderFragment? ChildContent { get; set; } + + /// + /// The amount of extra padding to add to the bottom of the component. + /// + [Parameter] public int ExtraPadding { get; set; } +} diff --git a/src/framework/Elsa.Studio.Shared/Components/Well.razor b/src/framework/Elsa.Studio.Shared/Components/Well.razor new file mode 100644 index 0000000..db6161a --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/Well.razor @@ -0,0 +1,11 @@ +
+ @ChildContent +
+ +@code +{ + /// + /// The content to be rendered inside the component. + /// + [Parameter] public RenderFragment? ChildContent { get; set; } +} diff --git a/src/framework/Elsa.Studio.Shared/Components/Zone.razor b/src/framework/Elsa.Studio.Shared/Components/Zone.razor new file mode 100644 index 0000000..321e8af --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/Zone.razor @@ -0,0 +1,4 @@ +@foreach (var widget in Widgets) +{ + @widget.Render(Attributes) +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Components/Zone.razor.cs b/src/framework/Elsa.Studio.Shared/Components/Zone.razor.cs new file mode 100644 index 0000000..cd7ae68 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Components/Zone.razor.cs @@ -0,0 +1,45 @@ +using Elsa.Studio.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Components; + +/// +/// Represents a zone in which widgets can be rendered. +/// +public partial class Zone : IDisposable +{ + /// + /// Gets or sets the zone name. + /// + [Parameter] + public string Name { get; set; } = default!; + + /// + /// Gets or sets the attributes that are passed to the widgets. + /// + [Parameter] + public IDictionary Attributes { get; set; } = new Dictionary(); + + [Inject] private IWidgetRegistry WidgetRegistry { get; set; } = default!; + [Inject] private IFeatureService FeatureService { get; set; } = default!; + private ICollection Widgets { get; set; } = new List(); + + /// + protected override void OnInitialized() + { + FeatureService.Initialized += OnFeatureServiceInitialized; + Widgets = WidgetRegistry.List(Name).ToList(); + } + + private void OnFeatureServiceInitialized() + { + Widgets = WidgetRegistry.List(Name).ToList(); + StateHasChanged(); + } + + /// + public void Dispose() + { + FeatureService.Initialized -= OnFeatureServiceInitialized; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Converters/JsonPrimitiveToStringConverter.cs b/src/framework/Elsa.Studio.Shared/Converters/JsonPrimitiveToStringConverter.cs new file mode 100644 index 0000000..8835e9c --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Converters/JsonPrimitiveToStringConverter.cs @@ -0,0 +1,43 @@ +using System.Globalization; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elsa.Studio.Converters; + +/// +/// Converts primitives to and from JSON strings. +/// +public class JsonPrimitiveToStringConverter : JsonConverter +{ + /// + public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.True: + return "True"; + case JsonTokenType.False: + return "False"; + case JsonTokenType.Number when reader.TryGetInt64(out var l): + return l.ToString(); + case JsonTokenType.Number: + return reader.GetDouble().ToString(CultureInfo.InvariantCulture); + case JsonTokenType.String when reader.TryGetDateTimeOffset(out var datetime): + return datetime.ToString(); + case JsonTokenType.String: + return reader.GetString()!; + default: + { + // Use JsonElement as fallback. + using var document = JsonDocument.ParseValue(ref reader); + return document.RootElement.Clone().ToString(); + } + } + } + + /// + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) + { + writer.WriteStringValue(value); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Converters/JsonStringToIntConverter.cs b/src/framework/Elsa.Studio.Shared/Converters/JsonStringToIntConverter.cs new file mode 100644 index 0000000..1374ae2 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Converters/JsonStringToIntConverter.cs @@ -0,0 +1,35 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elsa.Studio.Converters; + +/// +/// Converts strings to and from integers. +/// +public class JsonStringToIntConverter : JsonConverter +{ + /// + public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.String: + { + var stringValue = reader.GetString(); + if (int.TryParse(stringValue, out var intValue)) + return intValue; + break; + } + case JsonTokenType.Number: + return reader.GetInt32(); + } + + throw new JsonException($"Unable to convert {reader.TokenType} to {nameof(Int32)}."); + } + + /// + public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Elsa.Studio.Shared.csproj b/src/framework/Elsa.Studio.Shared/Elsa.Studio.Shared.csproj new file mode 100644 index 0000000..013ecca --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Elsa.Studio.Shared.csproj @@ -0,0 +1,23 @@ + + + + Elsa Studio shared services and components. + elsa studio framework + Elsa.Studio + + + + + + + + + + + + + + + + + diff --git a/src/framework/Elsa.Studio.Shared/Elsa.Studio.Shared.csproj.DotSettings b/src/framework/Elsa.Studio.Shared/Elsa.Studio.Shared.csproj.DotSettings new file mode 100644 index 0000000..d38f41f --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Elsa.Studio.Shared.csproj.DotSettings @@ -0,0 +1,3 @@ + + True + True \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Extensions/ClaimsExtensions.cs b/src/framework/Elsa.Studio.Shared/Extensions/ClaimsExtensions.cs new file mode 100644 index 0000000..f8f2e37 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Extensions/ClaimsExtensions.cs @@ -0,0 +1,20 @@ +using System.Security.Claims; + +namespace Elsa.Studio.Extensions; + +/// +/// Contains extension methods for . +/// +public static class ClaimsExtensions +{ + /// + /// Determines whether the "exp" claim is expired. + /// + public static bool IsExpired(this IEnumerable claims) + { + var expString = claims.FirstOrDefault(x => x.Type == "exp")?.Value.Trim(); + var exp = !string.IsNullOrEmpty(expString) ? long.Parse(expString) : 0; + var expiresAt = DateTimeOffset.FromUnixTimeSeconds(exp); + return expiresAt < DateTimeOffset.UtcNow; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Extensions/ServiceCollectionExtensions.cs b/src/framework/Elsa.Studio.Shared/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..390276f --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,33 @@ +using Elsa.Studio.Branding; +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization.Time; +using Elsa.Studio.Localization.Time.Providers; +using Elsa.Studio.Monaco.Handlers; +using Elsa.Studio.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Extensions; + +/// +/// Adds shared services to the service collection. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds shared services to the service collection. + /// + public static IServiceCollection AddSharedServices(this IServiceCollection services) + { + services.AddScoped(); + + // TODO: Move this to a new package; either specific to JS, or perhaps a general Monaco package that supports multiple languages. + // We'll decide once we add support for more languages. + services.AddScoped(); + + // Time services. + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + return services; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/FodyWeavers.xml b/src/framework/Elsa.Studio.Shared/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/FodyWeavers.xsd b/src/framework/Elsa.Studio.Shared/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Layouts/BasicLayout.razor b/src/framework/Elsa.Studio.Shared/Layouts/BasicLayout.razor new file mode 100644 index 0000000..edb3104 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Layouts/BasicLayout.razor @@ -0,0 +1,30 @@ +@using Elsa.Studio.Contracts +@inherits LayoutComponentBase +@implements IDisposable +@inject IThemeService ThemeService + + + + + + + @Body + + +@code { + + private MudTheme CurrentTheme => ThemeService.CurrentTheme; + + protected override void OnInitialized() + { + ThemeService.CurrentThemeChanged += OnThemeChanged; + StateHasChanged(); + } + + public void Dispose() + { + ThemeService.CurrentThemeChanged -= OnThemeChanged; + } + + private void OnThemeChanged() => StateHasChanged(); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Layouts/MainLayout.razor b/src/framework/Elsa.Studio.Shared/Layouts/MainLayout.razor new file mode 100644 index 0000000..48d3d06 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Layouts/MainLayout.razor @@ -0,0 +1,61 @@ +@inherits LayoutComponentBase + + + + + + + + + + + @foreach (var appBarItem in AppBarService.AppBarItems) + { + @appBarItem + } + + + + + @if (IsDarkMode) + { + + } + else + { + + } + + + + + + @BrandingProvider.Branding + +
+ +
+
+ + + + @Body + + + @if (context is UnauthorizedAccessException) + { + @UnauthorizedComponent + } + else + { + + + @context.GetType().Name: @context.Message + + + } + + + + +
\ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Layouts/MainLayout.razor.cs b/src/framework/Elsa.Studio.Shared/Layouts/MainLayout.razor.cs new file mode 100644 index 0000000..b4bc9e0 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Layouts/MainLayout.razor.cs @@ -0,0 +1,94 @@ +using Blazored.LocalStorage; +using Elsa.Studio.Branding; +using Elsa.Studio.Components; +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Services; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Web; +using MudBlazor; + +namespace Elsa.Studio.Layouts; + +/// +/// The main layout for the application. +/// +public partial class MainLayout : IDisposable +{ + private bool _drawerOpen = true; + private ErrorBoundary? _errorBoundary; + + [Inject] private IThemeService ThemeService { get; set; } = null!; + [Inject] private IAppBarService AppBarService { get; set; } = null!; + [Inject] private IUnauthorizedComponentProvider UnauthorizedComponentProvider { get; set; } = null!; + [Inject] private IFeatureService FeatureService { get; set; } = null!; + [Inject] private IDialogService DialogService { get; set; } = null!; + [Inject] private IBrandingProvider BrandingProvider { get; set; } = null!; + [Inject] private IServiceProvider ServiceProvider { get; set; } = null!; + [CascadingParameter] private Task? AuthenticationState { get; set; } + private MudTheme CurrentTheme => ThemeService.CurrentTheme; + private bool IsDarkMode => ThemeService.IsDarkMode; + private RenderFragment UnauthorizedComponent => UnauthorizedComponentProvider.GetUnauthorizedComponent(); + + /// + protected override void OnInitialized() + { + ThemeService.CurrentThemeChanged += OnThemeChanged; + AppBarService.AppBarItemsChanged += OnAppBarItemsChanged; + } + + /// + protected override async Task OnInitializedAsync() + { + if (AuthenticationState != null) + { + var authState = await AuthenticationState; + if (authState.User.Identity?.IsAuthenticated == true && !authState.User.Claims.IsExpired()) + { + await FeatureService.InitializeFeaturesAsync(); + StateHasChanged(); + } + } + else + { + await FeatureService.InitializeFeaturesAsync(); + StateHasChanged(); + } + } + + /// + protected override void OnParametersSet() + { + _errorBoundary?.Recover(); + } + + private void OnThemeChanged() => StateHasChanged(); + private void OnAppBarItemsChanged() => InvokeAsync(StateHasChanged); + + private void DrawerToggle() + { + _drawerOpen = !_drawerOpen; + } + + private void ToggleDarkMode() + { + ThemeService.IsDarkMode = !ThemeService.IsDarkMode; + } + + private async Task ShowProductInfo() + { + await DialogService.ShowAsync($"Elsa Studio {ToolVersion.GetDisplayVersion()}", new DialogOptions + { + FullWidth = true, + MaxWidth = MaxWidth.ExtraSmall, + CloseButton = true, + CloseOnEscapeKey = true + }); + } + + void IDisposable.Dispose() + { + ThemeService.CurrentThemeChanged -= OnThemeChanged; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Localization/Time/Components/Timestamp.razor b/src/framework/Elsa.Studio.Shared/Localization/Time/Components/Timestamp.razor new file mode 100644 index 0000000..3b88607 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Localization/Time/Components/Timestamp.razor @@ -0,0 +1 @@ +@GetDisplayString() \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Localization/Time/Components/Timestamp.razor.cs b/src/framework/Elsa.Studio.Shared/Localization/Time/Components/Timestamp.razor.cs new file mode 100644 index 0000000..dec9eb6 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Localization/Time/Components/Timestamp.razor.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Localization.Time.Components; + +public partial class Timestamp : ComponentBase +{ + /// + /// Gets or sets the timestamp to display. + /// + [Parameter] public DateTimeOffset? Value { get; set; } + + /// + /// Gets or sets the format to use when displaying the timestamp. + /// + [Parameter] public string Format { get; set; } = "G"; + + /// + /// Gets or sets the string to display when is null. + /// + [Parameter] public string EmptyString { get; set; } = string.Empty; + + [Inject] private ITimeFormatter TimeFormatter { get; set; } = default!; + + private string GetDisplayString() + { + return Value == null ? EmptyString : TimeFormatter.Format(Value.Value, Format); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Localization/Time/Contracts/ITimeFormatter.cs b/src/framework/Elsa.Studio.Shared/Localization/Time/Contracts/ITimeFormatter.cs new file mode 100644 index 0000000..eeec9c1 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Localization/Time/Contracts/ITimeFormatter.cs @@ -0,0 +1,15 @@ +namespace Elsa.Studio.Localization.Time; + +/// +/// Formats a date and time value based on the preferred time zone provided by . +/// +public interface ITimeFormatter +{ + /// + /// Formats the specified date and time value. + /// + /// The date and time value to format. + /// The format to use. Defaults to "G". + /// The string to return when is null. + string Format(DateTimeOffset? value, string format = "G", string emptyString = ""); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Localization/Time/Contracts/ITimeZoneProvider.cs b/src/framework/Elsa.Studio.Shared/Localization/Time/Contracts/ITimeZoneProvider.cs new file mode 100644 index 0000000..2000113 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Localization/Time/Contracts/ITimeZoneProvider.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Localization.Time; + +/// +/// Provides the preferred time zone. +/// +public interface ITimeZoneProvider +{ + /// + /// Gets the preferred time zone. + /// + TimeZoneInfo GetTimeZone(); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Localization/Time/Implementations/DefaultTimeFormatter.cs b/src/framework/Elsa.Studio.Shared/Localization/Time/Implementations/DefaultTimeFormatter.cs new file mode 100644 index 0000000..3b37c57 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Localization/Time/Implementations/DefaultTimeFormatter.cs @@ -0,0 +1,20 @@ +using System.Globalization; + +namespace Elsa.Studio.Localization.Time; + +/// +/// A default implementation that leverages the currently installed . +/// +public class DefaultTimeFormatter(ITimeZoneProvider timeZoneProvider) : ITimeFormatter +{ + /// + public string Format(DateTimeOffset? value, string format, string emptyString) + { + if (value == null) + return emptyString; + + var timeZone = timeZoneProvider.GetTimeZone(); + var localTime = TimeZoneInfo.ConvertTime(value.Value, timeZone); + return localTime.ToString(format, CultureInfo.CurrentCulture); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Localization/Time/Providers/LocalTimeZoneProvider.cs b/src/framework/Elsa.Studio.Shared/Localization/Time/Providers/LocalTimeZoneProvider.cs new file mode 100644 index 0000000..6cee7c7 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Localization/Time/Providers/LocalTimeZoneProvider.cs @@ -0,0 +1,14 @@ +namespace Elsa.Studio.Localization.Time.Providers; + +/// +/// Provides the preferred time zone based on the server's local time zone. +/// +public class LocalTimeZoneProvider : ITimeZoneProvider +{ + /// + public TimeZoneInfo GetTimeZone() + { + var timeZoneId = TimeZoneInfo.Local.Id; + return TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Localization/Time/Providers/UtcTimeZoneProvider.cs b/src/framework/Elsa.Studio.Shared/Localization/Time/Providers/UtcTimeZoneProvider.cs new file mode 100644 index 0000000..15451b8 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Localization/Time/Providers/UtcTimeZoneProvider.cs @@ -0,0 +1,13 @@ +namespace Elsa.Studio.Localization.Time.Providers; + +/// +/// Provides the UTC time zone. +/// +public class UtcTimeZoneProvider : ITimeZoneProvider +{ + /// + public TimeZoneInfo GetTimeZone() + { + return TimeZoneInfo.Utc; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Models/DataPanelItem.cs b/src/framework/Elsa.Studio.Shared/Models/DataPanelItem.cs new file mode 100644 index 0000000..e288505 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Models/DataPanelItem.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Models; + +public record DataPanelItem(string Label, string? Text = null, string? Link = null, Func? OnClick = null); \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Models/DataPanelModel.cs b/src/framework/Elsa.Studio.Shared/Models/DataPanelModel.cs new file mode 100644 index 0000000..6ce0efa --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Models/DataPanelModel.cs @@ -0,0 +1,19 @@ +namespace Elsa.Studio.Models; + +public class DataPanelModel : List +{ + public DataPanelModel() + { + } + + public DataPanelModel(IEnumerable collection) : base(collection) + { + } + + public void Add(string label, string? text = null, string? link = null) => Add(new DataPanelItem(label, text, link)); +} + +public static class DataPanelModelLinqExtensions +{ + public static DataPanelModel ToDataPanelModel(this IEnumerable items) => new(items); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Monaco/Contracts/IMonacoHandler.cs b/src/framework/Elsa.Studio.Shared/Monaco/Contracts/IMonacoHandler.cs new file mode 100644 index 0000000..1267066 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Monaco/Contracts/IMonacoHandler.cs @@ -0,0 +1,14 @@ +using Elsa.Studio.Models; + +namespace Elsa.Studio.Contracts; + +/// +/// Allows extensions to customize Monaco editor behavior, such as configuring intellisense. +/// +public interface IMonacoHandler +{ + /// + /// Invoked when the Monaco editor is initialized. + /// + ValueTask InitializeAsync(MonacoContext context); +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Monaco/Handlers/JavaScriptMonacoHandler.cs b/src/framework/Elsa.Studio.Shared/Monaco/Handlers/JavaScriptMonacoHandler.cs new file mode 100644 index 0000000..376ab78 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Monaco/Handlers/JavaScriptMonacoHandler.cs @@ -0,0 +1,33 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.Services; +using Microsoft.JSInterop; + +namespace Elsa.Studio.Monaco.Handlers; + +/// +/// Handles Monaco editor for JavaScript. +/// +public class JavaScriptMonacoHandler(IJSRuntime jsRuntime, TypeDefinitionService typeDefinitionService) + : IMonacoHandler +{ + /// + public async ValueTask InitializeAsync(MonacoContext context) + { + if (context.ExpressionDescriptor.Type != "JavaScript") + return; + + var activityDescriptor = context.CustomProperties.TryGetValue(nameof(ActivityDescriptor), out var activityDescriptorObj) ? (ActivityDescriptor)activityDescriptorObj : null; + var propertyDescriptor = context.CustomProperties.TryGetValue(nameof(PropertyDescriptor), out var propertyDescriptorObj) ? (PropertyDescriptor)propertyDescriptorObj : null; + var workflowDefinitionId = context.CustomProperties.TryGetValue("WorkflowDefinitionId", out var workflowDefinitionIdObj) ? (string)workflowDefinitionIdObj : null; + var activityTypeName = activityDescriptor?.TypeName; + var propertyName = propertyDescriptor?.Name; + + if (activityTypeName == null || workflowDefinitionId == null) + return; + + var data = await typeDefinitionService.GetTypeDefinition(workflowDefinitionId, activityTypeName, propertyName); + await jsRuntime.InvokeVoidAsync("monaco.languages.typescript.javascriptDefaults.addExtraLib", data, null); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Monaco/Models/MonacoContext.cs b/src/framework/Elsa.Studio.Shared/Monaco/Models/MonacoContext.cs new file mode 100644 index 0000000..ab7335a --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Monaco/Models/MonacoContext.cs @@ -0,0 +1,9 @@ +using BlazorMonaco.Editor; +using Elsa.Api.Client.Resources.Scripting.Models; + +namespace Elsa.Studio.Models; + +/// +/// Represents a context for working with the Monaco editor. +/// +public record MonacoContext(StandaloneCodeEditor Editor, ExpressionDescriptor ExpressionDescriptor, IDictionary CustomProperties); \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/Services/TypeDefinitionService.cs b/src/framework/Elsa.Studio.Shared/Services/TypeDefinitionService.cs new file mode 100644 index 0000000..d6bdd65 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/Services/TypeDefinitionService.cs @@ -0,0 +1,20 @@ +using Elsa.Api.Client.Resources.Scripting.Contracts; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Services; + +/// +/// A service that provides TypeScript type definitions. +/// +public class TypeDefinitionService(IBackendApiClientProvider remoteBackendApiClientProvider) +{ + /// + /// Gets the type definition for the specified activity type. + /// + public async Task GetTypeDefinition(string definitionId, string activityTypeName, string propertyName, CancellationToken cancellationToken = default) + { + var api = await remoteBackendApiClientProvider.GetApiAsync(cancellationToken); + var data = await api.GetTypeDefinitions(definitionId, new(definitionId, activityTypeName, propertyName), cancellationToken); + return await data.Content.ReadAsStringAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/WellKnownSyntaxNames.cs b/src/framework/Elsa.Studio.Shared/WellKnownSyntaxNames.cs new file mode 100644 index 0000000..35ba3f8 --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/WellKnownSyntaxNames.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio; + +public class WellKnownSyntaxNames +{ + public const string Literal = "Literal"; + public const string Object = "Object"; +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shared/_Imports.razor b/src/framework/Elsa.Studio.Shared/_Imports.razor new file mode 100644 index 0000000..be93a1c --- /dev/null +++ b/src/framework/Elsa.Studio.Shared/_Imports.razor @@ -0,0 +1,6 @@ +@using Microsoft.AspNetCore.Components.Web +@using BlazorMonaco +@using BlazorMonaco.Editor +@using MudBlazor +@using Elsa.Studio.Components +@using Elsa.Studio.Services \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shell/App.razor b/src/framework/Elsa.Studio.Shell/App.razor new file mode 100644 index 0000000..be6d73f --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/App.razor @@ -0,0 +1,32 @@ +@inherits StudioComponentBase + + + @if (!AuthorizationIsDisabled) + { + + + + + Authorizing + + + + @UnauthorizedComponentProvider.GetUnauthorizedComponent() + + + + } + else + { + + + } + + + + Not found + + Sorry, there's nothing at this address. + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shell/App.razor.cs b/src/framework/Elsa.Studio.Shell/App.razor.cs new file mode 100644 index 0000000..9971cf0 --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/App.razor.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using Elsa.Studio.Contracts; +using Elsa.Studio.Shell.Options; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Options; + +namespace Elsa.Studio.Shell; + +public partial class App +{ + [Inject] private IEnumerable Modules { get; set; } = null!; + + [Inject] private IUnauthorizedComponentProvider UnauthorizedComponentProvider { get; set; } = null!; + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + + [Inject] private IOptions ShellOptions { get; set; } = null!; + + private IEnumerable AdditionalAssemblies { get; set; } = null!; + + private bool AuthorizationIsDisabled => ShellOptions.Value.DisableAuthorization; + + /// + protected override void OnInitialized() + { + AdditionalAssemblies = Modules.Select(x => x.GetType().Assembly).Distinct().ToList(); + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shell/ComponentProviders/DefaultUnauthorizedComponentProvider.cs b/src/framework/Elsa.Studio.Shell/ComponentProviders/DefaultUnauthorizedComponentProvider.cs new file mode 100644 index 0000000..77f2626 --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/ComponentProviders/DefaultUnauthorizedComponentProvider.cs @@ -0,0 +1,23 @@ +using Elsa.Studio.Components; +using Elsa.Studio.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Shell.ComponentProviders; + +/// +/// Provides a that displays nothing. This is useful for scenarios where the login page is not required. If you need to display a login page, use LoginPageProvider" from the Login module instead or implement your own . +/// +public class DefaultUnauthorizedComponentProvider : IUnauthorizedComponentProvider +{ + /// + /// Returns a that displays nothing. + /// + public RenderFragment GetUnauthorizedComponent() + { + return builder => + { + builder.OpenComponent(0); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shell/Elsa.Studio.Shell.csproj b/src/framework/Elsa.Studio.Shell/Elsa.Studio.Shell.csproj new file mode 100644 index 0000000..6b5c468 --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/Elsa.Studio.Shell.csproj @@ -0,0 +1,17 @@ + + + + Elsa Studio application shell. + elsa studio framework + + + + + + + + + + + + diff --git a/src/framework/Elsa.Studio.Shell/Extensions/ServiceCollectionExtensions.cs b/src/framework/Elsa.Studio.Shell/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..022dc78 --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,41 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Shell.ComponentProviders; +using Elsa.Studio.Shell.Options; +using Microsoft.Extensions.DependencyInjection; +using MudBlazor; +using MudBlazor.Services; +using MudExtensions.Services; + +namespace Elsa.Studio.Shell.Extensions; + +/// +/// Provides extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the shell services. + /// + public static IServiceCollection AddShell(this IServiceCollection services, Action? configure = default) + { + configure ??= options => { options.DisableAuthorization = false; }; + services.Configure(configure); + + return services + .AddMudServices(config => + { + config.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.TopCenter; + config.SnackbarConfiguration.PreventDuplicates = false; + config.SnackbarConfiguration.NewestOnTop = false; + config.SnackbarConfiguration.ShowCloseIcon = true; + config.SnackbarConfiguration.VisibleStateDuration = 1000; + config.SnackbarConfiguration.HideTransitionDuration = 100; + config.SnackbarConfiguration.ShowTransitionDuration = 100; + config.SnackbarConfiguration.SnackbarVariant = Variant.Filled; + config.SnackbarConfiguration.MaxDisplayedSnackbars = 3; + }) + .AddMudExtensions() + .AddScoped() + ; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shell/FodyWeavers.xml b/src/framework/Elsa.Studio.Shell/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shell/FodyWeavers.xsd b/src/framework/Elsa.Studio.Shell/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shell/Options/ShellOptions.cs b/src/framework/Elsa.Studio.Shell/Options/ShellOptions.cs new file mode 100644 index 0000000..ca6135b --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/Options/ShellOptions.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Shell.Options; + +/// +/// Contains options for the component. +/// +public class ShellOptions +{ + /// + /// Gets or sets a value indicating whether authorization is disable. false by default. + /// + public bool DisableAuthorization { get; set; } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Shell/_Imports.razor b/src/framework/Elsa.Studio.Shell/_Imports.razor new file mode 100644 index 0000000..9a61f86 --- /dev/null +++ b/src/framework/Elsa.Studio.Shell/_Imports.razor @@ -0,0 +1,9 @@ +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Authorization +@using Microsoft.JSInterop +@using MudBlazor +@using Elsa.Studio.Components +@using Elsa.Studio.Layouts +@using Elsa.Studio.Shell \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Elsa.Studio.Translations.csproj b/src/framework/Elsa.Studio.Translations/Elsa.Studio.Translations.csproj new file mode 100644 index 0000000..67c9e57 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Elsa.Studio.Translations.csproj @@ -0,0 +1,26 @@ + + + + Provides various port providers for activities such as `FlowSwitch` and `SendHttpRequest`. + elsa studio module + + + + + true + true + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/src/framework/Elsa.Studio.Translations/ResxLocalizationProvider.cs b/src/framework/Elsa.Studio.Translations/ResxLocalizationProvider.cs new file mode 100644 index 0000000..0fa7cf7 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/ResxLocalizationProvider.cs @@ -0,0 +1,13 @@ +using System.Globalization; +using Elsa.Studio.Localization; + +namespace Elsa.Studio.Translations +{ + internal class ResxLocalizationProvider : ILocalizationProvider + { + public string? GetTranslation(string key) + { + return Elsa.Studio.Translations.Translations.ResourceManager.GetString(key, CultureInfo.CurrentUICulture); + } + } +} diff --git a/src/framework/Elsa.Studio.Translations/ServiceCollectionExtensions.cs b/src/framework/Elsa.Studio.Translations/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..31fece7 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/ServiceCollectionExtensions.cs @@ -0,0 +1,13 @@ +using Elsa.Studio.Localization; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Translations; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddTranslations(this IServiceCollection services) + { + services.AddSingleton(); + return services; + } +} \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.ar.resx b/src/framework/Elsa.Studio.Translations/Translations.ar.resx new file mode 100644 index 0000000..725ea2d --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.ar.resx @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ١٨٠ يوم + + + ٩٠ يوم + + + ١٤ يوم + + + ٧ أيام + + + ٣٠ يوم + + + وصف مختصر للعامل. + + + وصف مختصر للسر. + + + شرح مختصر لهذا المدخل. + + + شرح مختصر لسير العمل. + + + شرح مختصر لهذا المُخرج. + + + تصنيف خاص يتم تعيينه لسير العمل هذا. + + + تصنيف خاص يتم تحديده لهذا المُخرج. + + + وصف لدور وهدف هذا العامل. + + + تصنيف خاص يتم تحديده لهذا المدخل. + + + قيمة افتراضية. + + + وصف لدور وهدف هذا المتغير. + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.de.resx b/src/framework/Elsa.Studio.Translations/Translations.de.resx new file mode 100644 index 0000000..b6d542e --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.de.resx @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eine Beschreibung über das Geheimnis. + + + Eine Beschreibung über die Rolle und den Zweck dieser Eingabevariablen. + + + Ein technischer Name für die Funktion, die dieser Agent durchführt. Zum Beispiel: WriteCode + + + Aktivitäten + + + 14 Tage + + + 180 Tage + + + 30 Tage + + + 7 Tage + + + 90 Tage + + + Ein Standard-Wert. + + + Eine kurze Beschreibung des Agenten. + + + Eine kurze Beschreibung des Geheimnisses. + + + Eine kurze Beschreibung der Eingabe. + + + Eine kurze Beschreibung der Ausgabe. + + + Eine benutzerdefinierte Kategorie, um diese Ausgabe zu gruppieren. + + + Eine benutzerdefinierte Kategorie, um diese Eingabe zu gruppieren. + + + Eine Beschreibung über die Rolle und den Zweck dieses Agenten. + + + Eingabe hinzufügen + + + Ausgabe hinzufügen + + + Variable hinzufügen + + + Aktivitäts ID + + + Agent + + + Eine Beschreibung dieser Aktivität, die im Designer angezeigt werden soll. + + + Aktivierungsstrategie + + + API Schlüssel + + + API Schlüssel + + + Anwenden + + + Aggregation + + + Erlaube, dass dieser Workflow von einer Aktivität genutzt wird. + + + Kategorie + + + Unterbrechnung + + + Verzweigen + + + Leeren + + + Schließen + + + Wählen sie diese Option, wenn die Variable ein Array des ausgewählten Typs hält. + + + Klicken um einen neuen Workflow in einem Tab zu öffnen + + + Gemeinsame + + + Datum + + + Datumsfilter + + + Vollständig + + + Abgeschlossen + + + Zusammensetzung + + + Verbindungsdetails + + + Konsole + + + Korrelieren + + + Korrelations-ID + + + Erstellen von Agenten + + + API Schlüssel erstellen + + + Geheimnis erzeugen + + + Dienst erstellen + + + Cron + + + Dashboard + + + Standardeinstellung + + + Dauer + + + Bearbeiten + + + E-Mail + + + Aktivität + + + Hinzufügen + + + Angelegt am + + + Automatisch speichern + + + Abbrechen + + + Workflow schließen + + + Workflow anlegen + + + Entscheidung + + + Angelegt + + + Beschreibung + + + Ende + + + Standardwert + + + Verzögerung + + + Löschen + + + Anzeigenname + + + Ereignisse + + + Anzeigentext + + + Datei herunterladen + + + Ereignis + + + Allgemein + + + Fehlerhaft + + + Beendet + + + Beenden + + + Beendet am + + + Eine kurze Beschreibung des Workflows. + + + Agenten + + + Massenaktionen + + + Container + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.es.resx b/src/framework/Elsa.Studio.Translations/Translations.es.resx new file mode 100644 index 0000000..0f2cb33 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.es.resx @@ -0,0 +1,454 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 14 días + + + 180 días + + + 30 días + + + 7 días + + + 90 días + + + Una breve descripción del secreto. + + + Una breve descripción del flujo de trabajo. + + + Una breve descripción de esta entrada. + + + La categoría de actividad personalizada asignada a este flujo de trabajo como actividad. + + + Una categoría personalizada para agrupar esta entrada. + + + Un valor predeterminado. + + + Una descripción de la función y el propósito de esta variable de entrada. + + + Una descripción sobre el secreto. + + + El nombre de la función realizada por este agente. Por ejemplo: escribir código (WriteCode) + + + Reconocer eventos de origen de datos + + + Estrategia de activación + + + Actividades + + + Actividad + + + Identificación de la instancia de la actividad + + + Añadir + + + Añadir entrada + + + Añadir salida + + + Añadir variable + + + Agente + + + Agentes + + + Agrupación + + + Permitir que este flujo de trabajo se utilice como una actividad. + + + Clave API + + + Claves API + + + Aplicar + + + Actualización automática de los flujos de trabajo + + + Guardar automáticamente + + + Bifurcación + + + Pausa + + + Acciones masivas + + + Cancelar + + + Categoría + + + Cerrar flujo de trabajo + + + Común + + + Terminado + + + Composición + + + Cadenas de conexión + + + Consola + + + Correlación + + + Crear clave API + + + Cerrar + + + Crear agente + + + Identificación de la correlación + + + Una descripción de la función y el propósito de este agente. + + + Una breve descripción del agente. + + + Una breve descripción de esta salida. + + + Flujos de trabajo de envío masivo + + + Una categoría personalizada para agrupar esta salida. + + + Una descripción de esta actividad que se muestra en el diseñador. + + + Marque esta opción si la variable contiene una matriz del tipo seleccionado. + + + Haga clic para abrir una nueva pestaña de flujo de trabajo + + + Completo + + + Recipiente + + + Limpiar + + + Crear Secreto + + + Crear Servicio + + + Creado + + + Crear flujo de trabajo + + + Cron + + + Escritorio + + + Fecha + + + Filtros de Fecha + + + Decisión + + + Configuración por defecto + + + Valor por defecto + + + ID de Definición + + + ID de Versión de Definición + + + Suspensión + + + Eliminar + + + Descripción + + + Detalles + + + Enviar flujo de trabajo + + + Editar + + + Correo electrónico + + + Fin + + + Ingrese una lista de posibles salidas para este flujo de trabajo. + + + Evento + + + Eventos + + + Procesar Excel + + + Configuración de Ejecución + + + Ejecuciones + + + Expira + + + Exportar + + + Exportar el flujo de trabajo actual como archivo JSON. + + + Fallo + + + Finalizar + + + Finalizado + + + Flujo + + + Penalización de Frecuencia + + + Creación + + + Exportar esta versión como un archivo JSON. + + + Definiciones + + + Descargar Archivo + + + Duración + + + Expira en + + + Texto mostrado + + + Nombre para mostrar + + + Finalizado + + + Versión de Definición + + + Función + + + General + + + HTTP + + + ID + + + Importar + + + Estrategia de incidentes + + + Incidentes + + + Información + + + Info + + + Instancias + + + Última versión + + + Cargando + + + Tokens máximos + + + Metadata + + + Nombre + + + El nombre de la actividad. Otras actividades pueden hacer referencia a las actividades nombradas. + + + Nunca + + + No + + + No se han encontrado agentes + + + No se han encontrado API keys + + + No hay resultados asociados con esta ejecución. + + + No hay salidas asociadas con esta ejecución. + + + Abrir archivo + + + Importar un archivo JSON que contenga datos del flujo de trabajo para anular el contenido del flujo de trabajo actual. + + + Bucles + + + Estrategia de persistencia de logs + + + Ok + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.fa.resx b/src/framework/Elsa.Studio.Translations/Translations.fa.resx new file mode 100644 index 0000000..3a611e6 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.fa.resx @@ -0,0 +1,442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 14 روز + + + گروه سفارشی این ورودی. + + + 180 روز + + + توضیح مختصر خروجی. + + + توضیحی از این فعالیت که در ویرایشگر نمایش داده میشود. + + + توضیح مختصر کلید. + + + گروه سفارشی این خروجی. + + + 7 روز + + + 90 روز + + + توضیح مختصر رابط. + + + توضیح مختصر فرآیند. + + + توضیح مختصر ورودی. + + + گروه سفارشی فعالیت جهت اتصال فرآیند به آن. + + + مقدار پیشفرض. + + + توضیح نقش و هدف این متغیر ورودی. + + + توضیحی در مورد کلید. + + + نام فنی تابعی که این رابط انجام میدهد. مانند: WriteCode + + + توضیح نقش و هدف این رابط. + + + 30 روز + + + تایمر + + + افزودن + + + افزودن ورودی + + + افزودن خروجی + + + افزودن متغیر + + + استراتژی فعالسازی + + + اکتیویتی + + + اکتیویتی‌ها + + + زمان + + + این خروجی یک آرایه است + + + این وروددی یک آرایه است + + + نوع + + + مقدار + + + متغیرها + + + بله + + + شناسه اکتیویتی در اجرا + + + عامل + + + عامل‌ها + + + تجمیع + + + استفاده از این فرایند به عنوان اکیویتی. + + + API Key + + + API Keys + + + اعمال + + + به روزرسانی خودکار فرآیندهای مرتبط + + + ذخیره خودکار + + + انشعاب + + + توقف + + + عملیات دسته‌ای + + + اجرای دسته‌ای فرآیندها + + + در صورتی که متغیر شامل آرایه‌ای از نوع انتخاب شده است این گزینه را فعال نمایید. + + + لغو + + + دسته + + + پاکسازی + + + تب فرایند جدید + + + بستن + + + بستن فرآیند + + + عمومی + + + تکمیل + + + تکمیل شده + + + ترکیب + + + Connection Strings + + + کنسول + + + کانتینر + + + ایجاد عامل + + + ایجاد API Key + + + ایجاد رمز + + + ایجاد سرویس + + + ایجاد شده + + + ایجاد شده در + + + ایجاد فرآیند + + + کرون + + + پیشخوان + + + تاریخ + + + فیلترهای تاریخ + + + تصمیم + + + تنظیمات پیفرض + + + مقدار پیش‌فرض + + + تاخیر + + + حذف + + + توضیحات + + + جزییات + + + عنوان + + + نمایش متن + + + دانلود فایل + + + مدت + + + ویرایش + + + ایمیل + + + پایان + + + لیستی از خروجی‌های ممکن برای این فرایند را وارد نمایید. + + + رویداد + + + رویدادها + + + تنظیمات اجرا + + + انقضا + + + اجراها + + + انقضا تا + + + استخراج + + + استخراجی فرآیند جاری در قالی فایل JSON. + + + استخراج نسخه جاری در قالب فایل JSON. + + + خطا + + + خاتمه + + + خاتمه یافته + + + خاتمه یافته در + + + جریان + + + حلقه FOR + + + تابع + + + نام تابع + + + کلی + + + دارای رخداد + + + اچ تی تی پی + + + شناسه + + + شناسه اکتیویتی. + + + ویژگیهای ورودی + + + ورودی/خروجی + + + ورودی‌ها + + + ورودی + + + اجراها + + + عدد صحیح + + + در حال بارگذاری + + + نام + + + جریمه تکرار + + + جدیدترین نسخه + + + لیست کشویی + + + ویرایشگر جیسون + + + لیست چک‌باکس ها + + + لیست رادیو‌باتن ها + + + یک ورودی با این نام از قبل موجود است. + + + انتخابگر خروجی + + + یک ویرایشگر کد + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.fr.resx b/src/framework/Elsa.Studio.Translations/Translations.fr.resx new file mode 100644 index 0000000..c56900f --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.fr.resx @@ -0,0 +1,544 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 14 jours + + + 180 jours + + + 30 jours + + + 7 jours + + + 90 jours + + + Description courte de l'agent. + + + Description courte du secret. + + + Activité + + + Ajouter + + + Ajouter variable + + + Clé d'API + + + Clés d'API + + + Appliquer + + + Annuler + + + Console + + + Valeur par défaut + + + Durée + + + Modifier + + + Détails + + + Supprimer + + + Description + + + Fin + + + Paramètres d'éxécution + + + Exécutions + + + Expire dans + + + Nom de la Fonction + + + Valeur + + + Variables + + + Version + + + Historique de version + + + Voir + + + Valeur par défaut. + + + Catégorie + + + Tableau de bord + + + Chaînes de connexion + + + Evènement + + + Evènements + + + Email + + + Expiration + + + Fonction + + + Exporter + + + Mis à jour + + + Utiliser cette version + + + Utilisé + + + Activités + + + Agent + + + Agents + + + Sauvegarde automatique + + + Fermer + + + Créer une clé d'API + + + Date + + + Configuration par défaut + + + HTTP + + + ID + + + Information + + + A brève description de la sortie. + + + Une brève description de l'entrée. + + + Une brève description du workflow. + + + Une catégorie d'activité personnalisée à assigner à ce workflow en tant qu'activité. + + + Une activité personnalisée via laquelle grouper cette sortie. + + + Une activité personnalisée via laquelle grouper cette entrée. + + + Une description au sujet du rôle et du but de cet agent. + + + Une description au sujet du rôle et du but de cette variable en entrée. + + + Une description au sujet du secret. + + + Une description de cette activité à afficher dans le concepteur. + + + Un nom technique pour la fonction que cet agent exécute. Par exemple : WriteCode + + + Stratégie d'activation + + + Id d'instance de l'activité + + + Ajouter sortie + + + Ajouter entrée + + + Aggrégation + + + Autoriser ce workflow à être utilisé en tant qu'activité. + + + Branchement + + + Actions en lot + + + Effacer + + + Cliquer pour ouvrir un nouvel onglet de workflow + + + Fermer workflow + + + Terminer + + + Terminé + + + Composition + + + Conteneur + + + Corréler + + + ID de Corrélation + + + Créer agent + + + Créer Secret + + + Créer Service + + + Créé + + + Créé le + + + Créer workflow + + + Cron + + + Filtres de date + + + Décision + + + ID de définition + + + Version de définition + + + ID de version de définition + + + Définitions + + + Nom d'affichage + + + Texte d'affichage + + + Télécharger fichier + + + Saisir une liste de sorties possibles pour ce workflow. + + + Parseur Excel + + + Export le workflow actuel en tant que fichier JSON. + + + Exporter cette version en tant que fichier JSON. + + + Finir + + + Fini + + + Fini à + + + Général + + + A des incidents + + + L'ID de l'activité. + + + Importer + + + Importe a fichier JSON contenant des données de workflow pour écraser les contenus du workflow en cours. + + + Entrée + + + Propriétés en entrée + + + Entrée/sortie + + + Entrées + + + Instances + + + Journal + + + Dernière version + + + Chargement + + + Stratégie de persistence de log + + + Jetons Max + + + Métadonnées + + + Nom + + + Le nom de l'activité. Les activités nommées peuvent être référencées par d'autres activités. + + + Jamais + + + Non + + + Aucun agent trouvé + + + Aucune clé d'API trouvée + + + Aucune entrée + + + Aucune sortie associée avec cette exécution. + + + Aucun résultat de sortie associé avec cette exécution. + + + Aucune sortie + + + Aucun secret trouvé + + + Aucun service trouvé + + + Aucun état associé avec cette exécution. + + + Aucune variable + + + Aucun définition de workflow trouvée + + + Aucune instance de workflow trouvée + + + Ok + + + Ouvrir fichier + + + Sortie + + + Propriétés de sortie + + + Sorties + + + Parseur + + + Persistence de log + + + Propriétés + + + Publier + + + Publier évènement + + + Publié + + + Version publiée + + + Publier le workflow en cours + + + Lignes par page + + + Exécuter + + + Exécuter de manière asynchrone + + + Exécuter JavaScript + + + Exécuter Python + + + Exécuter la tâche + + + Exécuter le workflow + + + Enregister + + + Enregistrer le fichier + + + Rechercher ... + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.nl.resx b/src/framework/Elsa.Studio.Translations/Translations.nl.resx new file mode 100644 index 0000000..a3e0e48 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.nl.resx @@ -0,0 +1,991 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 14 dagen + + + Een korte omschrijving van deze input. + + + Een korte omschrijving van deze output. + + + 90 dagen + + + Een korte omschrijving van de secret. + + + Een standaardwaarde. + + + Activity Instance ID + + + Agenten + + + Gemaakt op + + + Geen uitkomst gekoppeld aan deze uitvoering. + + + Is op of na + + + De naam van de agent. + + + Temperatuur + + + Gestart + + + De omschrijving van de outputvariabele. + + + Status + + + Taak + + + string + + + Toon incidenten + + + Substatus + + + Alle evenementen + + + Start van de workflow + + + Incidenten + + + + + + De straf voor het herhalen van een token. Een hogere straf vermindert de kans op herhaling en bevordert meer variatie in de gegenereerde tekst. + + + + + + De straf voor het herhalen van een token. Een hogere straf vermindert de kans op herhaling en bevordert meer variatie in de gegenereerde tekst. + + + + + + De naam van de nieuwe agent. + + + + + + De naam van de variabele. + + + De plugin die de agent kan gebruiken. + + + De naam van de nieuwe workfow. + + + De naam van het nieuwe geheim. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lees data uit database + + + Functienaam + + + Gebeurtenissen + + + Lussen + + + De ID van de activiteit. + + + Ingangen + + + Planning + + + Weergave tekst + + + Workflow uitvoeren + + + Bereik + + + Nee + + + Beheer alle dingen + + + Fout + + + Publiceer + + + + + + Algemeen + + + Publiceer de huidige workflow + + + Is een array + + + Voltooien + + + Exporteren + + + Gebeurtenis + + + De naam van de activiteit. Genaamde activiteiten kunnen door andere activiteiten worden gerefereerd. + + + Klik om een nieuw workflowtabblad te openen + + + Agent + + + Samenvoegen + + + HTTP + + + HTTP Request + + + ID + + + Einde + + + Standaardconfiguratie + + + Bezig met laden + + + Geen services gevonden + + + Compositie + + + Maximale tokens + + + Algemeen + + + Is voor + + + Cron + + + Parser + + + HTTP-bestandrespons + + + Uitkomst + + + Bulk Dispatch Workflows + + + Bepaal uitkomst + + + Geen status gekoppeld aan deze uitvoering. + + + 7 dagen + + + Bepaal naam + + + Een beschrijving van de secret. + + + + + + Info + + + int + + + Gepubliceerde versie + + + Taak uitvoeren + + + Verloopt + + + Geen agents gevonden + + + Duur + + + + + + Asynchroon uitvoeren + + + API sleutels + + + + + + Het .NET-type van de inputvariabele. + + + Verwijderen + + + Werkstroom sluiten + + + Substatus + + + Definitie ID + + + JavaScript uitvoeren + + + Workflow verzenden + + + Geen variabelen + + + + + + Bulk acties + + + API sleutel + + + Zoeken... + + + Geen inputs + + + Importeren + + + + + + Invoereigenschappen + + + Geheimen + + + Toepassen + + + Incidentstrategie + + + Bepaal workflow-contextparameter + + + Een korte omschrijving van de agent. + + + De naam van de functie die de agent zal uitvoeren. + + + Functie + + + Nooit + + + Zoek op naam, omschrijving, id, definitie-id + + + Activities + + + + + + HTTP Response + + + Activeringsstrategie + + + Zoek op naam, id, definitie-id, definitieversie-id, correlatie-id + + + Toon relatieve tijd + + + Toon geaccumuleerde tijd + + + Voltooid + + + Is niet + + + Container + + + Toestaan dat deze workflow als activity gebruikt kan worden. + + + Voor + + + HTTP Endpoint + + + + + + Agent aanmaken + + + Open AI-chataanvulling + + + Stroom + + + Naam + + + Rijen per pagina + + + Is na + + + Output toevoegen + + + Dagboek + + + Bewerken + + + + + + Open bestand + + + Verstuur e-mail + + + object + + + Breken + + + Geen API keys gevonden + + + Een beschrijving van deze activity die in de designer moet worden weergegeven. + + + API-sleutel aanmaken + + + Erken Datasource-event + + + Console + + + Is op of voor + + + Gepubliceerd + + + Exporteer de huidige workflow als een JSON-bestand. + + + Correleren + + + Service maken + + + HTTP Request (flow) + + + Executie instellingen + + + Services + + + Incidentaantal + + + Uikomsteigenschappen + + + Informatie + + + Omwisselen (flow) + + + Status + + + Verbindingsreeksen + + + Activity + + + + + + Bestand bewaren + + + Sluiten + + + De levensduur van dit geheim + + + Een technische naam voor de functie die deze agent uitvoert. Bijvoorbeeld: WriteCode + + + Geen workflow-definities gevonden + + + Een aangepaste categorie om deze output te groeperen. + + + Incidenten + + + Geheim aanmaken + + + + + + Omwisselen + + + Terugrollen naar deze versie + + + Executies + + + Sub-workflow uitkomsten + + + Voltooid op + + + Prompt-template + + + Annuleren + + + 180 dagen + + + Invoer + + + Als + + + Start + + + + + + 30 dagen + + + + + + Aggregatie + + + Uitvoeren + + + Een aangepaste categorie waarin deze invoer wordt gegroepeerd. + + + Definities + + + Excel parser + + + Python uitvoeren + + + + + + Toon evenementen binnen het bereik van de huidige container + + + Details + + + + + + Vertakken + + + + + + Opslag + + + Workflow maken + + + Een beschrijving van de rol en het doel van deze invoervariabele. + + + Scripting + + + + + + Variable toevoegen + + + Verloopt over + + + Weergave naam + + + Een korte omschrijving van de workflow. + + + + + + Metadata + + + Automatisch opslaan + + + Lees data uit configuratie / runtime + + + Vork (stroom) + + + Beslissing + + + Voltooien + + + Het .NET-type van de outputvariabele. + + + + + + Instanties + + + Datum filters + + + + + + E-mail + + + OpenAI tekst-naar-afbeelding + + + Eigenschappen + + + Log persistence strategie + + + + + + Sub-workflow inputs + + + + + + Definitie versie + + + Een beschrijving van de rol en het doel van deze agent. + + + Gemaakt + + + Het maximale aantal tokens te genereren. Laat leeg voor maximum. + + + + + + Geen workflow-instances gevonden + + + OK + + + Plugins + + + Voltooid + + + Bestand downloaden + + + Uitkomsten + + + Importeer een JSON-bestand met workflowgegevens om de inhoud van de huidige workflow te overschrijven. + + + + + + Definitie versie ID + + + + + + Instellingen + + + + + + Uitkomsten + + + Correlatie ID + + + Dashboard + + + Bewaren + + + + + + Primitieven + + + Datum + + + Laatste versie + + + Start op + + + Geen uitkomsten + + + Publiceer evenement + + + Omschrijving + + + Een aangepaste activity categorie om aan deze workflow-als-activity toe te wijzen. + + + Geen secrets gevonden + + + Voer een lijst in met mogelijke uitkomsten voor deze workflow. + + + + + + Gebruikende workflows automatisch bijwerken + + + Selecteer deze optie als de variabele een array van het geselecteerde type bevat. + + + Bepaal variabele + + + Sub-workflow + + + Geheim + + + + + + + + + Logpersistentie + + + Frequentiestraf + + + Is + + + Vertraging + + + Input toevoegen + + + Leegmaken + + + Heeft incidenten + + + Categorie + + + Toevoegen + + + Standaardwaarde + + + Geen uitkomsten gekoppeld aan deze uitvoering. + + + Exporteer deze versie als een JSON-bestand. + + + Invoer/uitvoer + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.pt.resx b/src/framework/Elsa.Studio.Translations/Translations.pt.resx new file mode 100644 index 0000000..e602741 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.pt.resx @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 180 dias + + + 90 dias + + + Uma descrição resumida do segredo. + + + Uma descrição resumida do workflow. + + + Uma descrição resumida do input. + + + Uma categoria personalizada de atividade a dar a este workflow-como-atividade. + + + Uma categoria personalizada de como agrupar este output. + + + Um valor padrão. + + + Uma descrição sobre o papel e propósito deste agente. + + + Uma descrição sobre o papel e propósito desta variável de input. + + + Uma descrição sobre o segredo. + + + Uma descrição desta atividade para aparecer no designer. + + + Reconhecer evento de Datasource + + + Estratégia de ativação + + + Atividades + + + Atividade + + + ID de Instância da Atividade + + + Adicionar + + + Adicionar input + + + Adicionar output + + + Agente + + + Permitir que este workflow seja usado como uma atividade. + + + Chave de API + + + Atualizar automaticamente workflows consumidores + + + Guardar automaticamente + + + Ramificar + + + Pausa + + + Ações em massa + + + Cancelar + + + Categoria + + + Seleciona esta opção se a variável contiver um array do tipo selecionado. + + + Limpar + + + Clica para abrir um novo separador de workflow + + + Fechar + + + Fechar workflow + + + Comum + + + Completo + + + Completado + + + Composição + + + Strings de Conexão + + + Consola + + + Container + + + Correlacionar + + + Criar Chave de API + + + Criar Serviço + + + Criado + + + Criado Em + + + Painel + + + Data + + + Filtros de Data + + + Decisão + + + Configuração por Omissão + + + ID de Definição + + + ID de versão de Definição + + + Definições + + + Atraso + + + Apagar + + + Descrição + + + Detalhes + + + Expedir Workflow + + + Nome de Apresentação + + + 14 dias + + + 30 dias + + + Uma descrição resumida do agente. + + + 7 dias + + + Uma descrição resumida do output. + + + Uma categoria personalizada de como agrupar este input. + + + Um nome técnico para a função que este agente performa. Por exemplo: EscreverCodigo + + + Adicionar variável + + + Agentes + + + Agregação + + + Chaves de API + + + Aplicar + + + Expedição em Massa de Workflows + + + Criar Segredo + + + ID de Correlação + + + Valor por omissão + + + Versão de Definição + + + Criar Agente + + + Criar workflow + + + Cron + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.resx b/src/framework/Elsa.Studio.Translations/Translations.resx new file mode 100644 index 0000000..b69e3a6 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.resx @@ -0,0 +1,1632 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 14 days + + + 180 days + + + 30 days + + + 7 days + + + 90 days + + + A brief description of the agent. + + + A brief description of the secret. + + + A brief description of the workflow. + + + A brief description of this input. + + + A brief description of this output. + + + A custom activity category to assign this workflow-as-an-activity to. + + + A custom category by which to group this input. + + + A custom category by which to group this output. + + + A default value. + + + A description about the role and purpose of this agent. + + + A description about the role and purpose of this input variable. + + + A description about the secret. + + + A description of this activity to be displayed in the designer. + + + A technical name for the function that this agent perform. For example: WriteCode + + + Acknowledge Datasource Event + + + Activation strategy + + + Activities + + + Activity + + + Activity Instance ID + + + Add + + + Add input + + + Add output + + + Add variable + + + Agent + + + Agents + + + Aggregation + + + Allow this workflow to be used as an activity. + + + API Key + + + API Keys + + + Apply + + + Auto-update consuming workflows + + + Auto-save + + + Branching + + + Break + + + Bulk actions + + + Bulk Dispatch Workflows + + + Cancel + + + Category + + + Check this option if the variable holds an array of the selected type. + + + Clear + + + Click to open a new workflow tab + + + Close + + + Close workflow + + + Common + + + Complete + + + Completed + + + Composition + + + Connection Strings + + + Console + + + Container + + + Correlate + + + Correlation ID + + + Create Agent + + + Create API Key + + + Create Secret + + + Create Service + + + Created + + + CreatedAt + + + Create workflow + + + Cron + + + Dashboard + + + Date + + + Date Filters + + + Decision + + + Default configuration + + + Default value + + + Definition ID + + + Definition version + + + Definition version ID + + + Definitions + + + Delay + + + Delete + + + Description + + + Details + + + Dispatch Workflow + + + Display name + + + Display text + + + Download File + + + Duration + + + Edit + + + Email + + + End + + + Enter a list of possible outcomes for this workflow. + + + Event + + + Events + + + Excel Parser + + + Execution Settings + + + Executions + + + Expires + + + Expires In + + + Export + + + Export the current workflow as a JSON file. + + + Export this version as a JSON file. + + + Fault + + + Finish + + + Finished + + + FinishedAt + + + Flow + + + For + + + Fork (flow) + + + Frequency Penalty + + + Function + + + Function Name + + + General + + + Has Incidents + + + HTTP + + + HTTP Endpoint + + + HTTP File Response + + + HTTP Request + + + HTTP Request (flow) + + + HTTP Response + + + ID + + + The ID of the activity. + + + If + + + Import + + + Import a JSON file containing workflow data to override the current workflow's contents. + + + Incident Strategy + + + IncidentCount + + + Incidents + + + Info + + + Information + + + Input + + + Input Properties + + + Input/output + + + Inputs + + + Instances + + + int + + + Is + + + Is After + + + Is array + + + Is Before + + + Is Not + + + Is on or After + + + Is on or Before + + + Join + + + Journal + + + Latest version + + + Loading + + + Log Persistence Strategy + + + Looping + + + Manage all the things + + + Max Tokens + + + Metadata + + + Name + + + The name of the activity. Named activities can be referenced by other activities. + + + Never + + + No + + + No agents found + + + No API keys found + + + No inputs + + + No outcomes associated with this execution. + + + No output associated with this execution. + + + No outputs + + + No secrets found + + + No services found + + + No state associated with this execution. + + + No variables + + + No workflow definitions found + + + No workflow instances found + + + object + + + Ok + + + Open File + + + OpenAIChatCompletion + + + OpenAITextToImage + + + Outcomes + + + Output + + + Output Properties + + + Outputs + + + Parser + + + Log Persistence + + + Plugins + + + Presence Penalty + + + Primitives + + + Prompt Template + + + Properties + + + Publish + + + Publish Event + + + Published + + + Published version + + + Publish the current workflow + + + Read Data from Configuration / Runtime + + + Read Data from Database + + + Rollback to this version + + + Rows Per Page + + + Run + + + Run Asynchronously + + + Run JavaScript + + + Run Python + + + Run Task + + + Run workflow + + + Save + + + Save File + + + Scheduling + + + Scope + + + Scripting + + + Search... + + + Search on name, id, definition id, definition version id, correlation id + + + Search on name, description, id, definition id + + + Secret + + + Secrets + + + Send Email + + + Services + + + Set Name + + + Set Output + + + Set Variable + + + Set Workflow Context Parameter + + + Settings + + + Show accumulated time + + + Show events scoped to current container + + + Show incidents + + + Show relative time + + + Showing all events + + + Showing incidents + + + Start + + + Start at + + + Start of workflow + + + Started + + + State + + + Status + + + Storage + + + string + + + Sub status + + + Sub-Workflow + + + Sub-Workflow Inputs + + + Sub-Workflow Outputs + + + SubStatus + + + Switch + + + Switch (flow) + + + Task + + + Temperature + + + The .NET type of the input variable. + + + The .NET type of the output variable. + + + The description of the output variable. + + + The lifetime of this secret + + + The maximum number of tokens to generate. Leave empty for maximum. + + + The name of the agent. + + + The name of the function that the agent will execute. + + + The name of the new agent. + + + The name of the new secret. + + + The name of the new workflow. + + + The name of the variable. + + + The penalty for repeating any one token. A higher presence penalty will reduce the likelihood of token repetition, fostering more varied text generation. + + + The penalty for repeating any one token. A higher frequency penalty will reduce the likelihood of token repetition, fostering more varied text generation. + + + The plugins that the agent can use. + + + The scope of the secret helps the UI to filter available options from dropdown lists. + + + The secret value. + + + The services that the agent requires. + + + The settings of the service in JSON format. + + + The system prompt template that the agent will use. + + + The technical name of the API key. + + + The technical name of the input variable. When referencing this variable in the prompt template, use this name. + + + The technical name of the input. + + + The technical name of the service. + + + The temperature of the model. Higher values mean the model will take more risks. Try 0.1 for results that are very close to what the model was trained on. Try 0.9 for very creative results. + + + The type of the service. + + + The user-friendly name of this input. + + + The user-friendly name of this output. + + + The value of the API key. + + + There are currently no inputs defined. + + + There are currently no outputs defined. + + + There are currently no variables defined. + + + This activity does not have any common properties. + + + This activity does not have any input properties. + + + This activity does not have any output properties. + + + This input is an array + + + This output is an array + + + This variable is an array + + + Time + + + Timer + + + Top Probability determines the cumulative probability threshold for token selection during text generation. Lower values will result in less diversity, making the model pick from the most probable tokens only. Higher values will allow for more diverse outputs, as the model will consider a wider range of tokens. + + + TopP + + + Trigger workflow + + + Type + + + UI Hint + + + Unable to make changes as the workflow or application is currently in read-only mode + + + Unpublish + + + Unpublish the current workflow. + + + Updated + + + UpdatedAt + + + Usable as activity + + + Use JSON Response + + + Use this version + + + Used + + + Used to define the initial instructions or context that the Semantic Kernel agent will use to generate responses. This template guides the agent's behavior and helps it understand the role it needs to play or the tasks it needs to perform. + + + Value + + + Variables + + + Version + + + Version history + + + View + + + Webhooks + + + When checked, the workflow will be executed asynchronously. + + + When you publish a new version, all of the consuming workflows will be updated to point to the new version of this workflow. + + + Whether to show the description in the designer. + + + Workflow Context + + + Workflow Context Settings + + + Workflow Contexts + + + Workflow definitions Editor + + + Workflow instances + + + The name of the workflow. + + + Workflows + + + Write Line + + + Yes + + + You are running in read-only mode. Workflow operations are disabled + + + You can find documentation and examples here + + + Incident handling strategy + + + A checkbox + + + A code editor + + + A dropdown list + + + A JSON editor + + + A list of checkboxes + + + A list of radio buttons + + + A single line of text input + + + A variable picker + + + A variable with this name already exists in the current scope. + + + A workflow definition picker + + + A workflow output definition picker + + + A workflow with this name already exists. + + + An input for multiple words, like a tagging input + + + An input with this name already exists. + + + An outcome picker + + + Are you sure you want to cancel all running workflow instances of this workflow definition? + + + Are you sure you want to cancel the selected workflow instances? + + + Are you sure you want to cancel this workflow instance? + + + Are you sure you want to delete the selected input? + + + Are you sure you want to delete the selected output? + + + Are you sure you want to delete the selected variable? + + + Are you sure you want to delete the selected versions? + + + Are you sure you want to delete the selected workflow instances? + + + Are you sure you want to delete the selected workflows? + + + Are you sure you want to delete this version? + + + Are you sure you want to delete this workflow instance? + + + Are you sure you want to delete this workflow? + + + Are you sure you want to publish the selected workflows? + + + Are you sure you want to unpublish the selected workflows? + + + Cancel running workflow instances? + + + Cancel selected workflow instances? + + + Cancel workflow instance? + + + Checkbox + + + Checklist + + + Code editor + + + {0} consuming workflow(s) updated + + + Create input + + + Create output + + + Create variable + + + Default + + + Default Strategy + + + Delete selected input? + + + Delete selected output? + + + Delete selected variable? + + + Delete selected versions + + + Delete selected workflow instances? + + + Delete selected workflows? + + + Delete version + + + Delete workflow instance? + + + Delete workflow? + + + Dropdown + + + Edit output + + + Edit variable + + + Edit Workflow Definition + + + Enter the expression that will be used to determine the log persistence strategy for this property. + + + Failed to import {0} workflow definitions. Errors: {1} + + + imported successfully. + + + Inherit + + + JSON editor + + + Message + + + Multi line + + + Multi text + + + Multiple lines of text input + + + New workflow + + + No workflows found to import. + + + No workflows were imported. + + + None + + + Not executed + + + Not usable as activity. + + + One workflow consuming a published workflow has been updated + + + One workflow is already published + + + One workflow is already unpublished + + + One workflow is not found + + + One workflow is published + + + One workflow is unpublished + + + Outcome picker + + + Output picker + + + Please enter a name for the input. + + + Please enter a name for the output. + + + Please enter a name for the variable. + + + Please enter a name for the workflow. + + + Publish selected workflows? + + + Radio list + + + Readonly + + + Show description + + + Single line + + + Successfully imported + + + Successfully imported 1 workflow definition. + + + Successfully imported one instance + + + Successfully started workflow + + + The commit strategy to use that controls when the workflow state should be committed. + + + The ID of the variable. + + + The read-only workflows will not be affected. + + + The text to display in the designer. + + + The workflow cannot be started + + + Timestamp + + + Unpublish selected workflows? + + + Upload JSON and/or ZIP files containing workflow data to import. + + + Variable picker + + + When checked, this activity can trigger this workflow. + + + When checked, this activity is the start of this workflow. + + + Workflow definition picker + + + workflow definitions. + + + Workflow published + + + Workflow published with Not Found activities + + + Workflow retracted + + + Workflow saved + + + Workflow unpublished + + + Workflow was already published + + + workflows are already published + + + workflows are already unpublished + + + workflows are not found + + + workflows are published + + + workflows are unpublished + + + workflows consuming published workflows have been updated + + + Delete version {0} + + + Successfully imported {0} instances + + + Successfully imported {0} workflow definitions. + + + {0} workflows are already published + + + {0} workflows are already unpublished + + + {0} workflows are not found + + + {0} workflows are published + + + {0} workflows are unpublished + + + {0} workflows consuming published workflows have been updated + + + {0} {1} imported successfully. + + + Failed to import {0} {1}. + + + Auto layout + + + Center + + + Zoom to fit the screen + + + A function to compute the correlation ID to associate a dispatched workflow with. + + + A list of expected outcomes to handle. + + + A list of expected status codes to handle. + + + A value that allows to add the Authorization header without validation. + + + Always allow the creation + + + Branches + + + Break out of a loop. + + + Cancelled + + + Condition + + + Content Type + + + Correlation ID Function + + + Default Item Input Key + + + Disable Authorization Header Validation + + + Executes javaScript code + + + Executing + + + Expected Status Codes + + + Method + + + Mode + + + Request Content. + + + Result + + + Running + + + Supported Methods + + + The Authorization header value to send with the request. For example: Bearer {some-access-token} + + + The content to send with the request. Can be a string, an object, a byte array or a stream. + + + The content type to use when sending the request. + + + The data source to use for dispatching the workflows. + + + The default key to use for the input name when sending the current item to the dispatched workflow. Will not be used if the Items field contain a list of dictionaries + + + The definition ID of the workflows to dispatch. + + + The HTTP method to use when sending the request. + + + The HTTP methods to accept. + + + The join mode determines whether this activity should continue as soon as one inbound path comes in (Wait Any), or once all inbound paths have executed (Wait All). + + + The outcome or set of outcomes to complete this activity with. + + + The path to associate with the workflow. + + + The switch mode determines whether the first match should be scheduled, or all matches. + + + The URL to download the file from. + + + Time Duration + + + Trigger execution at a specific time in the future. + + + URL + + + Validation Result + + + Workflow Definition + + + Add case + + + Data + + + Label + + + Result + + + Zoom to fit + + + Always allow the creation of a new workflow instance. + + + Assign the current value to the specified variable. + + + Code + + + Controls whether the end step is upper/lowerbound inclusive or exclusive. True (inclusive) by default. + + + Current Value + + + Interval + + + Outer Bound Inclusive + + + Payload + + + Step + + + The end step. + + + The items to iterate through. + + + The set of values to iterate. + + + The start step. + + + The step size. To count down, enter a negative number. + + + Variable + + + Provider Type + + + Configuration + + + Exclude + + + Include + + + Load + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.ru.resx b/src/framework/Elsa.Studio.Translations/Translations.ru.resx new file mode 100644 index 0000000..857c94b --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.ru.resx @@ -0,0 +1,991 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 14 дней + + + 180 дней + + + 7 дней + + + 90 дней + + + Краткое описание этого вывода. + + + Пользовательская категория, по которой можно сгруппировать эти выходные данные. + + + 30 дней + + + Краткое описание агента. + + + Краткое описание секрета. + + + Краткое описание рабочего процесса. + + + Краткое описание этого ввода. + + + Значение по-умолчанию. + + + Описание роли и назначения этой входной переменной. + + + Описание секрета. + + + Пользовательская категория действий, которой можно присвоить этот рабочий процесс как действие. + + + Пользовательская категория, по которой можно сгруппировать эти входные данные. + + + Описание этого действия будет отображено в конструкторе. + + + Описание роли и назначения этого агента. + + + Стратегия активации + + + Подтверждение события источника данных + + + Действия + + + Техническое название функции, которую выполняет этот агент. Например: WriteCode + + + Действие + + + ID экземпляра действия + + + Добавить + + + Добавить вход + + + Добавить выход + + + Добавить переменную + + + Агент + + + Агенты + + + Агрегация + + + Ключ API + + + Ключи API + + + Применить + + + Использовать рабочий процесс в качестве действия. + + + Автообновление трудоемких рабочих процессов + + + Автосохранение + + + Ветвление + + + Прерывание + + + Массовые действия + + + Массовые вызовы рабочих процессов + + + Отмена + + + Категория + + + Установите этот флажок, если переменная содержит массив выбранного типа. + + + Очистить + + + Нажмите, чтобы открыть новую вкладку рабочего процесса + + + Закрыть + + + Закрыть рабочий процесс + + + Общий + + + Завершить + + + Завершенный + + + Композиция + + + Строки подключения + + + Консоль + + + Контейнер + + + Соотнести + + + ID соотношения (корреляции) + + + Создать агента + + + Создать ключ API + + + Создать секрет + + + Создать службу + + + Создан + + + Создан в + + + Создать рабочий процесс + + + Крон + + + Дэшборд + + + Дата + + + Фильтры по дате + + + Решение + + + Стандартная конфигурация + + + Значение по-умолчанию + + + ID определения + + + Версия определения + + + ID версии определения + + + Определения + + + Задержка + + + Удалить + + + Описание + + + Детали + + + Отправка рабочего процесса + + + Отображаемое название + + + Отображаемый текст + + + Скачать файл + + + Длительность + + + Редактировать + + + Email + + + Конец + + + Введите список возможных результатов для этого рабочего процесса. + + + Событие + + + События + + + Обработчик Excel + + + Запуски + + + Истекает + + + Истекает в + + + Экспорт + + + Экспорт текущего рабочего процесса как файл JSON. + + + Ошибка + + + Завершить + + + Завершен + + + Завершен в + + + Поток + + + Цикл For + + + Разделить (поток) + + + Ограничение по частоте + + + Функция + + + Название функции + + + Основной + + + Есть инциденты + + + HTTP + + + Точка доступа HTTP + + + Файловый ответ HTTP + + + Запрос HTTP + + + Запрос HTTP (поток) + + + Ответ HTTP + + + ID + + + ID действия. + + + Если (условие) + + + Импорт + + + Импортировать файл JSON, содержащий данные рабочего процесса для перезаписи текущего контента рабочих процессов. + + + Стратегия инцидентов + + + Количество инцидентов + + + Инциденты + + + Краткая информация + + + Информация + + + Ввод + + + Свойства ввода + + + Ввод/вывод + + + Вводы + + + Экземпляры + + + int + + + Есть + + + Это после + + + Это массив + + + Это до + + + Это не + + + Это на или после + + + Это на или до + + + Объединить + + + Журнал + + + Последняя версия + + + Загрузка + + + Стратегия сохранения журнала + + + Название действия. На именованные действия могут ссылаться другие действия. + + + Никогда + + + Нет + + + Агенты не найдены + + + API ключи не найдены + + + Нет вводов + + + Никаких результатов, связанных с этим выполнением, нет. + + + Никаких выходных данных, связанных с этим выполнением, нет. + + + Нет состояния, связанного с этим выполнением. + + + Нет переменных + + + Не найдено определений рабочих процессов + + + Не найдено экземпляров рабочих процессов + + + object + + + Ок + + + Открыть файл + + + Плагины + + + Примитивы + + + Свойства + + + Опубликовать + + + Опубликовать события + + + Опубликовано + + + Откатить до этой версии + + + Строк на страницу + + + Выполнить JavaScript + + + Выполнить рабочий процесс + + + Сохранить + + + Сохранить файл + + + Планирование + + + Поиск по названию, описанию, идентификатору, идентификатору определения + + + Отправить Email + + + Службы + + + Установить название + + + Установить вывод + + + Установить переменную + + + Показать события в области текущего контейнера + + + Показать инциденты + + + Показывать все события + + + Показывать инциденты + + + Начать + + + Начать в + + + Начало рабочего процесса + + + Начат + + + Состояние + + + Статус + + + string + + + Дополнительный статус + + + Подпроцесс + + + Переключатель + + + Переключатель (поток) + + + Задача + + + Температура + + + .Net тип переменной ввода. + + + .Net тип перменной вывода. + + + Описание переменной вывода. + + + Время жизни этого секрета + + + Название агента. + + + Экспорт этой версии рабочего процесса как файл JSON. + + + Параметры запуска + + + Циклы + + + Матаданные + + + Сценарии + + + Результаты + + + Штраф за присутствие + + + Показать накопленное время + + + Область + + + Максимальное кол-во токенов + + + Настройки + + + Управлять всеми делами + + + Название + + + Прочитать данные из БД + + + Секреты + + + Показать относительное время + + + Установить параметр контекста рабочего процесса + + + Секреты не найдены + + + Изображение на основе описания OpenAI + + + Вывод + + + Свойства вывода + + + Парсер + + + Нет выводов + + + Выводы + + + Секрет + + + Службы не найдены + + + Выполнить задачу + + + Выполнить асинхронно + + + Выполнить Python + + + Опубликовать текущий рабочий процесс + + + Выполнение OpenAIChat + + + Поиск... + + + Устойчивость журнала + + + Шаблон подсказки + + + Опубликованная версия + + + Прочитать данные из конфигурации / На лету (Runtime) + + + Выполнить + + + Поиск по имени, идентификатору, идентификатору определения, идентификатору версии определения, идентификатору корреляции + + + Хранилище + + + Выводы подпроцесс + + + Вводы продпроцесса + + + Подстатус + + + Максимальное количество токенов для генерации. Оставьте поле пустым для максимального количества. + + + Код + + + Редактор кода + + + Редактировать переменную + + + {0} {1} успешно импортировано. + + + Условие + + + Выполнить javaScript код + + + Исполнение + + + Добавить сценарий + + + Название переменной. + + + Имя нового рабочего процесса. + + + Сервисы, необходимые агенту. + + + Плагины, которые может использовать агент. + + + Область действия секрета помогает интерфейсу фильтровать доступные варианты в выпадающих списках. + + + Значение секрета. + + + Настройки сервиса в формате JSON. + + + Шаблон системного запроса, который будет использовать агент. + + + Техническое имя API ключа. + + + Техническое имя входной переменной. При обращении к этой переменной в шаблоне запроса используйте это имя. + + + Использовать JSON ответ + + + Использовать эту версию + + + Значение + + + Переменные + + + Версия + + + История версий + + + Просмотр + + + Вебхуки + + + Стратегия обработки инцидентов + + + Входной параметр с таким именем уже существует. + + + Выпадающий список + + + Не выполнено + + + Нельзя использовать как активность. + + + Показать описание + + + Успешно импортировано + + + Рабочий процесс успешно запущен + + + ID переменной. + + + Текст, отображаемый в дизайнере. + + + Невозможно запустить рабочий процесс + + + Загрузите файлы JSON и/или ZIP, содержащие данные рабочих процессов, для импорта. + + + Не удалось импортировать {0} {1}. + + + По центру + + + Масштабировать по размеру экрана + + + Список ожидаемых кодов состояния для обработки. + + + Всегда разрешать создание + + + Тип содержимого + + + Метод + + + Содержимое запроса. + + + Результат + + + Поддерживаемые методы + + + Значение заголовка Authorization, отправляемое с запросом. Например: Bearer {some-access-token} + + + Содержимое для отправки с запросом. Может быть строкой, объектом, байтовым массивом или потоком. + + + Тип содержимого, используемый при отправке запроса. + + + HTTP-метод, используемый при отправке запроса. + + + HTTP-методы, которые принимаются. + + + Путь, который следует ассоциировать с рабочим процессом. + + + Продолжительность времени + + + Результат проверки + + + Переменная + + + Масштабировать по размеру + + + Вы действительно хотите отменить выбранные экземпляры рабочих процессов? + + + Всегда разрешать создание нового экземпляра рабочего процесса. + + + Источник данных, используемый для запуска рабочих процессов. + + + Выбор переменной + + + {0} рабочих процессов опубликованы + + + Автоматическая компоновка + + + Прекращает выполнение цикла. + + + Отключить проверку заголовка авторизации + + + URL, откуда будет скачан файл. + + + URL + + + Присвоить текущее значение указанной переменной. + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.uk.resx b/src/framework/Elsa.Studio.Translations/Translations.uk.resx new file mode 100644 index 0000000..1e48892 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.uk.resx @@ -0,0 +1,1573 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 180 днів + + + 30 днів + + + Короткий опис секрету. + + + Короткий опис робочого процесу. + + + Короткий опис цього вводу. + + + Значення за замовчуванням. + + + 14 днів + + + Короткий опис агента. + + + Опис про роль та призначення даного агента. + + + 7 днів + + + Короткий опис цього виходу. + + + 90 днів + + + Спеціальна категорія, за якою групувати цей вихід. + + + Опис про секрет. + + + Опис цієї діяльності буде відображено в дизайнері. + + + Технічна назва функції, яку виконує цей агент. Наприклад: WriteCode + + + Підтвердити подію джерела даних + + + Стратегія активації + + + Діяльність + + + Діяльність + + + Ідентифікатор діяльності + + + Додати + + + Додайте вхідні дані + + + Додати вихід + + + Додайте змінну + + + Агент + + + Агенти + + + Агрегація + + + Дозволити використовувати цей робочий процес як дію. + + + Ключ API + + + Ключі API + + + Застосувати + + + Автоматичне оновлення споживаючих робочих процесів + + + Автозбереження + + + Розгалуження + + + Перерва + + + Масові дії + + + Робочі процеси масової розсилки + + + Скасувати + + + Категорія + + + Перевірте цей параметр, якщо змінна має масив вибраного типу. + + + Очистити + + + Натисніть, щоб відкрити нову вкладку робочого процесу + + + Закрити + + + Закритий робочий процес + + + Загальні + + + Повний + + + Виконаний + + + Композиція + + + Рядки підключення + + + Консоль + + + Контейнер + + + Співвіднести + + + ID кореляції + + + Створити агента + + + Створити ключ API + + + Створити секрет + + + Створено + + + Створити послугу + + + CreatedAt + + + Створити робочий процес + + + Cron + + + Приладова панель + + + Дата + + + Фільтри дат + + + Рішення + + + Конфігурація за замовчуванням + + + Значення за замовчуванням + + + ID визначення + + + Версія визначення + + + Ідентифікатор версії визначення + + + Визначення + + + Затримка + + + Видалити + + + Опис + + + Подробиці + + + Диспетчерський робочий процес + + + Відображуване ім'я + + + Відображення тексту + + + Завантажити файл + + + Тривалість + + + Редагувати + + + Електронна пошта + + + Кінець + + + Введіть список можливих результатів для цього робочого процесу. + + + Подія + + + Події + + + Парсер Excel + + + Параметри виконання + + + Страти + + + Термін дії закінчується + + + Експорт + + + Експортуйте поточний робочий процес як файл JSON. + + + Експортуйте цю версію як файл JSON. + + + Несправність + + + Закінчити + + + Готово + + + FinishedAt + + + Потік + + + Для + + + Штраф за частоту + + + Вилка (потік) + + + Функція + + + Назва функції + + + Загальний + + + Має інциденти + + + HTTP + + + Кінцева точка HTTP + + + Відповідь файлу HTTP + + + HTTP-запит + + + HTTP-запит (потік) + + + Відповідь HTTP + + + ID + + + Ідентифікатор діяльності. + + + Якщо + + + Імпорт + + + Імпортуйте файл JSON, що містить дані робочого циклу, щоб замінити вміст поточного робочого циклу. + + + Стратегія інциденту + + + IncidentCount + + + Інциденти + + + Інформація + + + Інформація + + + Введення + + + Властивості введення + + + Введення/виведення + + + Вхідні дані + + + Примірники + + + внутр + + + Є + + + Є після + + + Раніше + + + Не є + + + Чи є на або після + + + Чи до + + + Приєднуйтесь + + + Журнал + + + Остання версія + + + Завантаження + + + Стратегія збереження журналу + + + Зациклення + + + Керуйте всіма справами + + + Макс жетонів + + + Ім'я + + + Ніколи + + + Немає входів + + + Немає результатів, пов’язаних із цією стратою. + + + Немає виходів + + + Секретів не знайдено + + + Послуг не знайдено + + + Жодних змінних + + + Не знайдено екземплярів робочого процесу + + + об'єкт + + + Гаразд + + + Відкрити файл + + + OpenAIChatCompletion + + + OpenAITextToImage + + + Результати + + + Вихід + + + Вихідні властивості + + + Виходи + + + Парсер + + + Постійність журналу + + + Плагіни + + + Штраф за присутність + + + Примітиви + + + Шаблон запиту + + + Властивості + + + Опублікувати + + + Опублікувати подію + + + Опубліковано + + + Опублікована версія + + + Рядків на сторінці + + + Запуск + + + Запуск асинхронно + + + Запустіть JavaScript + + + Запустіть Python + + + Виконати завдання + + + Запустіть робочий процес + + + Планування + + + Область застосування + + + Сценарії + + + Пошук... + + + Пошук за назвою, описом, ідентифікатором, ідентифікатором визначення + + + Секрет + + + Секрети + + + Надіслати електронний лист + + + Послуги + + + Встановити назву + + + Встановити вихід + + + Встановити змінну + + + Встановити параметр контексту робочого процесу + + + Показати накопичений час + + + Показати події + + + Показати відносний час + + + Показ усіх подій + + + Показ інцидентів + + + Розпочато + + + Держава + + + Статус + + + Під статусом + + + Вхідні дані підпроцесу + + + Підробочі результати + + + Перемикач (потік) + + + Завдання + + + Тип .NET вхідної змінної. + + + Тип .NET вихідної змінної. + + + Максимальна кількість токенів для генерації. Залиште порожнім для максимуму. + + + Ім'я агента. + + + Назва нового секрету. + + + Назва нового робочого циклу. + + + Ім'я змінної. + + + Плагіни, які може використовувати агент. + + + Обсяг секрету допомагає інтерфейсу користувача фільтрувати доступні параметри зі спадних списків. + + + Секретна цінність. + + + Послуги, які вимагає агент. + + + Налаштування сервісу в форматі JSON. + + + Шаблон системної підказки, який використовуватиме агент. + + + Технічна назва ключа API. + + + Технічна назва вхідної змінної. Посилаючись на цю змінну в шаблоні підказки, використовуйте це ім’я. + + + Технічна назва послуги. + + + Тип послуги. + + + Зручна назва цього введення. + + + Зручна назва цього результату. + + + Значення ключа API. + + + Наразі не визначено жодного входу. + + + Наразі не визначено вихідних даних. + + + Наразі не визначено жодної змінної. + + + Ця діяльність не має вхідних властивостей. + + + Цей вхід є масивом + + + Ця змінна є масивом + + + Час + + + Таймер + + + TopP + + + Робочий процес тригера + + + Тип + + + Підказка інтерфейсу користувача + + + Неможливо внести зміни, оскільки робочий процес або програма зараз у режимі лише для читання + + + Скасувати публікацію + + + Скасувати публікацію поточного робочого процесу. + + + Оновлено + + + Оновлено в + + + Можна використовувати як діяльність + + + Значення + + + Змінні + + + Версія + + + Історія версій + + + Переглянути + + + Вебхуки + + + Коли ви публікуєте нову версію, усі споживчі робочі цикли буде оновлено, щоб вказувати на нову версію цього робочого циклу. + + + Контекст робочого процесу + + + Параметри контексту робочого процесу + + + Контексти робочого процесу + + + Екземпляри робочого процесу + + + Робочі процеси + + + Написати рядок + + + Так + + + Ви можете знайти документацію та приклади тут + + + Стратегія поводження з інцидентами + + + Старт + + + Температура + + + Опис вихідної змінної. + + + Тривалість життя цієї таємниці + + + Ця діяльність не має вихідних властивостей. + + + Технічна назва входу. + + + Ця діяльність не має спільних властивостей. + + + Цей вихід є масивом + + + Верхня ймовірність визначає кумулятивний поріг імовірності для вибору маркера під час генерації тексту. Менші значення призведуть до меншої різноманітності, що змусить модель вибирати лише найімовірніші маркери. Вищі значення дозволять отримати більш різноманітні результати, оскільки модель розглядатиме ширший діапазон токенів. + + + Використовуйте відповідь JSON + + + Використовуйте цю версію + + + Якщо позначено, робочий процес виконуватиметься асинхронно. + + + Редактор визначень робочого процесу + + + Ви працюєте в режимі лише для читання. Операції робочого циклу вимкнено + + + Початок робочого процесу + + + Спеціальна категорія діяльності, до якої можна призначити цей робочий процес як дію. + + + Початок о + + + Ні + + + Температура моделі. Вищі значення означають, що модель більше ризикуватиме. Спробуйте 0,1 для результатів, які дуже близькі до того, на якому навчалася модель. Спробуйте 0,9 для дуже творчих результатів. + + + Використовується для визначення початкових інструкцій або контексту, які агент семантичного ядра використовуватиме для створення відповідей. Цей шаблон спрямовує поведінку агента та допомагає йому зрозуміти роль, яку він має відігравати, або завдання, які він має виконувати. + + + Налаштування + + + Метадані + + + Показати події, пов’язані з поточним контейнером + + + Зберігання + + + Чи показувати опис у конструкторі. + + + Назва діяльності. На названі дії можуть посилатися інші дії. + + + Агентів не знайдено + + + Ім'я нового агента. + + + б/в + + + Опис ролі та призначення цієї вхідної змінної. + + + Ключі API не знайдено + + + Читання даних із бази даних + + + Пошук за назвою, ідентифікатором, ідентифікатором визначення, ідентифікатором версії визначення, ідентифікатором кореляції + + + Спеціальна категорія, за якою групувати цей вхід. + + + Немає вихідних даних, пов’язаних із цим виконанням. + + + Жодного стану, пов’язаного з цією стратою. + + + рядок + + + Підробочий процес + + + Назва функції, яку виконуватиме агент. + + + Штраф за повторення будь-якої однієї фішки. Вищий штраф за присутність зменшить ймовірність повторення маркера, сприяючи створенню більш різноманітного тексту. + + + Штраф за повторення будь-якої однієї фішки. Вищий штраф частоти зменшить ймовірність повторення маркера, сприяючи генерації більш різноманітного тексту. + + + Є масив + + + Визначення робочого процесу не знайдено + + + Зберегти + + + Підстатус + + + Назва робочого циклу. + + + Перемикач + + + Термін дії закінчується + + + Опублікувати поточний робочий процес + + + Читання даних із конфігурації / середовища виконання + + + Відкат до цієї версії + + + Зберегти файл + + + А Вибір змінних + + + А Вибір результатів + + + Ви впевнені, що бажаєте видалити вибраний вихід? + + + Ви впевнені, що бажаєте видалити цей робочий процес? + + + Контрольний список + + + Редактор коду + + + Оновлено споживаючих робочих процесів: {0} + + + Створіть змінну + + + За замовчуванням + + + Видалити вибрані версії + + + Видалити екземпляр робочого процесу? + + + Видалити робочий процес? + + + Редагувати вихід + + + Редагувати визначення робочого процесу + + + Редактор JSON + + + Жодного + + + Один робочий процес уже опубліковано + + + Вибір вихідних даних + + + Будь ласка, введіть назву для введення. + + + Якщо позначено, ця дія може ініціювати цей робочий процес. + + + Вибір визначення робочого процесу + + + {0} робочих процесів не знайдено + + + {0} {1} успішно імпортовано. + + + Опубліковано один робочий процес + + + Список радіокнопок + + + Багаторядкове введення тексту + + + Ви впевнені, що бажаєте видалити вибрані екземпляри робочого процесу? + + + Неможливо запустити робочий процес + + + Випадаючий список + + + Успішно імпортовано {0} визначень робочого процесу. + + + {0} робочих процесів уже опубліковано + + + Опубліковано {0} робочих процесів + + + Змінна з такою назвою вже існує в поточній області. + + + {0} робочих процесів скасовано + + + Засіб вибору визначення вихідних даних робочого процесу + + + Ви впевнені, що бажаєте опублікувати вибрані робочі процеси? + + + успішно імпортовано. + + + Вхід із такою назвою вже існує. + + + Видалити вибрані екземпляри робочого процесу? + + + А Редактор JSON + + + Ви впевнені, що бажаєте скасувати цей екземпляр робочого процесу? + + + Ви впевнені, що бажаєте видалити вибрані версії? + + + Ви впевнені, що бажаєте видалити вибрану змінну? + + + Робочі процеси не імпортовано. + + + Один робочий процес не знайдено + + + Один робочий процес не опублікований + + + Будь ласка, введіть назву для результату. + + + Введіть назву робочого циклу. + + + Ви впевнені, що хочете видалити цю версію? + + + Ви впевнені, що бажаєте видалити цей екземпляр робочого процесу? + + + Редагувати змінну + + + Тільки для читання + + + Один робочий процес уже не опубліковано + + + Робочий процес опубліковано + + + Успішно імпортовано 1 визначення робочого процесу. + + + Робочий процес збережено + + + Робочий цикл опубліковано з діями Not Found + + + Мітка часу + + + робочі процеси вже опубліковано + + + робочі процеси вже неопубліковані + + + Успішно імпортовано {0} примірників + + + Скасувати запущені екземпляри робочого процесу? + + + Створити вхід + + + Створити вихід + + + Видалити версію + + + Якщо позначено, ця дія є початком робочого процесу. + + + Введіть вираз, який використовуватиметься для визначення стратегії збереження журналу для цієї властивості. + + + Багаторядковий + + + Вибір результатів + + + Список прапорців + + + Введення тексту в один рядок + + + Засіб вибору визначення робочого процесу + + + Ідентифікатор змінної. + + + Робочий цикл із такою назвою вже існує. + + + Вхід для кількох слів, наприклад введення тегів + + + Ви впевнені, що бажаєте скасувати всі запущені екземпляри цього робочого циклу? + + + Скасувати вибрані екземпляри робочого процесу? + + + Видалити вибраний вихід? + + + Не вдалося імпортувати {0} визначень робочого процесу. Помилки: {1} + + + Не виконано + + + Опублікувати вибрані робочі процеси? + + + Ви впевнені, що бажаєте скасувати вибрані екземпляри робочого процесу? + + + Ви впевнені, що бажаєте видалити вибрані робочі процеси? + + + Ви впевнені, що бажаєте видалити вибраний вхід? + + + Текст для відображення в дизайнері. + + + А Прапорець + + + Ви впевнені, що бажаєте скасувати публікацію вибраних робочих процесів? + + + Скасувати екземпляр робочого процесу? + + + Прапорець + + + Мультитекст + + + Стратегія за замовчуванням + + + Видалити вибраний вхід? + + + Видалити вибрану змінну? + + + Спадний список + + + Видалити вибрані робочі процеси? + + + Список радіо + + + Успадкувати + + + Показати опис + + + Повідомлення + + + Оновлено один робочий цикл, який використовує опублікований робочий цикл + + + Новий робочий процес + + + Не знайдено робочих процесів для імпорту. + + + Не можна використовувати як діяльність. + + + Будь ласка, введіть назву для змінної. + + + Одна лінія + + + Успішно імпортовано + + + Успішно імпортовано один екземпляр + + + Робочий процес успішно розпочато + + + Вибір змінних + + + Стратегія фіксації для використання контролює, коли стан робочого циклу має бути фіксовано. + + + Це не вплине на робочі процеси лише для читання. + + + Скасувати публікацію вибраних робочих процесів? + + + публікуються робочі процеси + + + Завантажте JSON та/або ZIP-файли з даними робочого процесу для імпорту. + + + визначення робочого процесу. + + + Робочий процес відкликано + + + Робочий процес уже опубліковано + + + Робочий процес не опубліковано + + + Видалити версію {0} + + + робочі процеси не знайдено + + + робочі процеси неопубліковані + + + робочі процеси, які використовують опубліковані робочі процеси, оновлено + + + {0} робочих процесів уже скасовано + + + Оновлено {0} робочих процесів, які використовують опубліковані робочі процеси + + + Не вдалося імпортувати {0} {1}. + + + А Редактор коду + + + Ідентифікатор визначення робочих процесів, які потрібно відправити. + + + Список очікуваних кодів стану для обробки. + + + Шлях для зв’язування з робочим процесом. + + + Режим перемикання визначає, чи слід запланувати перший матч чи всі матчі. + + + Контролює, чи буде кінцевий крок включно чи виключно з верхньої/нижньої межі. Істина (включно) за замовчуванням. + + + Елементи для повторення. + + + Початковий крок. + + + Масштаб під розмір екрана + + + Режим + + + Результат + + + Автоматичний макет + + + Ідентифікаційна функція кореляції + + + Джерело даних для диспетчеризації робочих процесів. + + + Завжди дозволяйте створення нового екземпляра робочого процесу. + + + Центр + + + Функція для обчислення ідентифікатора кореляції, з яким пов’язується надісланий робочий процес. + + + Клавіша введення елемента за замовчуванням + + + Метод + + + Тип вмісту для використання під час надсилання запиту. + + + Запит вмісту. + + + Збільшити до розміру + + + Набір значень для повторення. + + + Метод HTTP для надсилання запиту. + + + Значення заголовка авторизації для надсилання із запитом. Наприклад: носій {some-access-token} + + + Результат або набір результатів для завершення цієї діяльності. + + + URL-адреса для завантаження файлу. + + + Мітка + + + Поточне значення + + + Розмір кроку. Для зворотного відліку введіть від’ємне число. + + + Вміст, який потрібно надіслати разом із запитом. Може бути рядком, об’єктом, масивом байтів або потоком. + + + Час Тривалість + + + Присвоїти поточне значення вказаній змінній. + + + Ключ за замовчуванням, який використовується як ім’я введення під час надсилання поточного елемента до робочого циклу відправлення. Не використовуватиметься, якщо поле Items містить список словників + + + Методи HTTP, які потрібно прийняти. + + + Режим об’єднання визначає, чи має продовжуватися ця діяльність, щойно надходить один вхідний шлях (Wait Any), чи після виконання всіх вхідних шляхів (Wait All). + + + Список очікуваних результатів для обробки. + + + Значення, яке дозволяє додати заголовок авторизації без перевірки. + + + Завжди дозволяти створення + + + Відділення + + + Вирватися з петлі. + + + Скасовано + + + Хвороба + + + Тип вмісту + + + Вимкнути перевірку заголовка авторизації + + + Виконує код javascript + + + Виконання + + + Очікувані коди стану + + + Запуск + + + Підтримувані методи + + + Запустити виконання в певний час у майбутньому. + + + URL + + + Результат перевірки + + + Визначення робочого процесу + + + Додати регістр + + + Дані + + + Результат + + + Код + + + Інтервал + + + Зовнішня межа включно + + + Корисне навантаження + + + Крок + + + Кінцевий крок. + + + змінна + + + Навантаження + + + Конфігурація + + + Тип постачальника + + + Виключити + + + Включати + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.zh-Hans.resx b/src/framework/Elsa.Studio.Translations/Translations.zh-Hans.resx new file mode 100644 index 0000000..b003614 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.zh-Hans.resx @@ -0,0 +1,1558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 180 天 + + + 30 天 + + + 7 天 + + + 90 天 + + + 工作流的简要描述。 + + + 代理的简要描述。 + + + 默认值。 + + + 活动 + + + 活动实例ID + + + 添加输入 + + + 添加变量 + + + 聚合 + + + 允许该工作流作为一个活动。 + + + 批量操作 + + + 批量调度工作流 + + + 取消 + + + 清空 + + + 点击打开一个新的工作流标签页 + + + 关闭 + + + 关闭工作流 + + + 公共 + + + 跳出 + + + 混合 + + + 控制台 + + + 容器 + + + 关联 + + + 关联ID + + + 创建 API Key + + + 创建 Service + + + 创建于 + + + Cron表达式 + + + 仪表盘 + + + 日期 + + + 日期筛选器 + + + 决策 + + + 默认配置 + + + 默认值 + + + 工作流定义版本ID + + + 工作流定义列表 + + + 删除 + + + 描述 + + + 调度工作流 + + + 显示名称 + + + 显示文本 + + + 编辑 + + + 结束 + + + 事件 + + + Excel 解析器 + + + Execution 列表 + + + 导出 + + + 导出该版本到JSON文件 + + + 错误 + + + 完成 + + + 已完成 + + + Flow + + + 14 天 + + + 输出的简要描述。 + + + 添加 + + + 输入的简要描述。 + + + secret的简要描述。 + + + 活动列表 + + + 添加输出 + + + 应用 + + + 自动保存 + + + 分类 + + + 完成 + + + 已完成 + + + 工作流定义ID + + + For + + + 工作流定义版本 + + + 延迟 + + + 创建 Secret + + + 已创建 + + + 创建工作流 + + + 详情 + + + 下载文件 + + + 分支 + + + Execution 设置 + + + 间隔 + + + 邮件 + + + 事件列表 + + + 导出当前工作流到JSON文件 + + + ID + + + 导入 + + + If + + + 完成于 + + + 激活策略 + + + 代理 + + + 代理列表 + + + API Key + + + 自动更新使用中的工作流 + + + API Keys + + + 连接字符串 + + + 创建代理 + + + 键入此工作流可能的结果列表。 + + + HTTP文件响应 + + + 此活动的ID。 + + + 信息 + + + 信息 + + + 输入属性列表 + + + 输入/输出 + + + 在此之后 + + + 不包含 + + + 连接 + + + 最新版本 + + + 加载中 + + + 日志持久化策略 + + + 否 + + + 输入列表为空 + + + 此执行过程没有任何结果。 + + + 没有变量列表 + + + 对象(Object) + + + 确认 + + + 打开文件 + + + 结果列表 + + + 输出 + + + 输出属性 + + + 输出列表 + + + 日志持久化 + + + 元数据 + + + 名称 + + + 属性列表 + + + 发布事件 + + + 已发布 + + + 发布当前工作流 + + + 从配置/运行时读取数据 + + + 从数据库读取数据 + + + 回退到此版本 + + + Secret + + + 发送电子邮件 + + + 服务 + + + 每页行数 + + + 运行 + + + 运行(异步) + + + 运行JavaScript + + + 运行Python + + + 运行工作流 + + + 保存文件 + + + 范围 + + + 设置列表 + + + 开始 + + + 已开始 + + + 状态 + + + 存储库 + + + 字符串 + + + 子工作流输入列表 + + + 新代理的名称。 + + + 子工作流输出列表 + + + 子状态 + + + 选择器 + + + 选择器(流模式) + + + 任务 + + + 输出变量的描述。 + + + 这个输出是一个数组 + + + 这个输入是一个数组 + + + 这个活动没有任何输出属性。 + + + 目前没有定义任何变量。 + + + 目前没有定义任何输入。 + + + 目前没有定义任何输出。 + + + 服务的类型。 + + + 变量列表 + + + 历史版本 + + + 视图 + + + 当您发布一个新版本时,所有的被使用工作流将被更新,以指向该工作流的新版本。 + + + 工作流上下文 + + + 工作流上下文列表 + + + 工作流定义编辑器 + + + 工作流实例 + + + 工作流的名称。 + + + 您正在以只读模式运行。工作流操作被禁止 + + + 你可以在这里找到文档和示例 + + + 版本 + + + Webhooks + + + 选中时,工作流将异步执行。 + + + 是否在设计器中显示描述。 + + + 工作流上下文设置 + + + 计时器 + + + 时间 + + + 这个变量是一个数组 + + + 这个活动没有任何输入属性。 + + + API密钥的值。 + + + 代理的名称。 + + + 代理将执行的函数的名称。 + + + 搜索… + + + 值 + + + 写行 + + + 是 + + + 搜索 名称,id,定义id,定义版本id,相关id + + + 搜索 名称,描述,id,定义id + + + 设置工作流上下文参数 + + + 设置输出 + + + 设置变量 + + + 显示所有事件 + + + 开始于 + + + 状态 + + + 子状态 + + + 子工作流 + + + 温度 + + + 活动的名称。命名活动后可以被其他活动引用。 + + + 此执行过程没有任何输出。 + + + 输出列表为空 + + + 插件列表 + + + 发布 + + + 已发布版本 + + + 保存 + + + HTTP 终节点 + + + HTTP请求 + + + HTTP请求(流模式) + + + HTTP响应 + + + 输入 + + + 导入一个包含工作流数据的JSON文件,以覆盖当前工作流的内容。 + + + 输入列表 + + + 实例列表 + + + 整型(Int) + + + 是数组 + + + 在此之前 + + + 关于此输入变量的角色和目的的描述。 + + + 分配给此工作流作为活动的自定义活动类别。 + + + 用于对此输入进行分组的自定义类别。 + + + 用于对此输出进行分组的自定义类别。 + + + 关于此密钥的描述。 + + + 此代理执行的功能名称。例如:编写代码(WriteCode) + + + 确认数据源事件 + + + 如果变量持有选定类型的数组,请勾选此选项。 + + + 过期 + + + 过期于 + + + 分支(流) + + + 频率惩罚 + + + 函数 + + + 函数名称 + + + 常规 + + + HTTP + + + 存在异常事件 + + + 异常事件数量 + + + 异常事件策略 + + + 异常事件列表 + + + 是 + + + 等于或在此之后 + + + 等于或在此之前 + + + 未找到任何代理 + + + 未找到任何 API keys + + + 未找到任何 secrets + + + 未找到任何服务 + + + 此执行过程没有任何状态。 + + + 未找到任何工作流实例 + + + 未找到任何工作流定义 + + + OpenAI对话模型(OpenAIChatCompletion) + + + OpenAI文本转图像模型(OpenAITextToImage) + + + 解析器 + + + 正循环中 + + + 管理所有事项 + + + 最大 Tokens 数量 + + + 从不 + + + 提示词模版 + + + 重复惩罚(Presence Penalty) + + + 运行Task + + + 设置名称 + + + 正计划中 + + + Secrets列表 + + + 显示累计时长 + + + 显示异常事件列表 + + + 正显示异常事件列表中 + + + 启动工作流 + + + 此 secret 的生命周期 + + + 此输入变量的.NET类型 + + + 此输出变量的.NET类型 + + + 可生成的最大tokens数量。留空时为可用的最大值。 + + + 新 secret 的名称。 + + + 新工作流的名称。 + + + 此变量的名称。 + + + 当Token重复时的惩罚。重复惩罚值越高,生成重复Token的可能性就越低,从而促进生成更多样化的文本。 + + + 此代理可用的插件列表 + + + 此服务的专业名称。 + + + 此输入的专业名称。 + + + 此 API key 的专业名称。 + + + 此输入变量的专业名称。在提示模板中引用此变量时,请使用此名称。 + + + 无法更改,因为当前工作流或应用处于只读模式。 + + + 用户界面提示 + + + 类型 + + + 触发工作流 + + + TopP + + + TopP 决定了文本生成过程中 Token 选择的累积概率阈值。较低的值会导致多样性减少,使模型仅从最可能的 Token 中选择。较高的值将允许输出更加多样化,因为模型会考虑更广泛的 Token 范围。 + + + 此活动没有任何公共属性。 + + + 此输出的显示文本。 + + + 此输入出的显示文本。 + + + 已使用 + + + 使用此版本 + + + 启用 JSON Response + + + 可用作活动 + + + 更新于 + + + 已更新 + + + 取消发布当前工作流。 + + + 取消发布 + + + 工作流列表 + + + 异常事件处理策略 + + + 在设计器中显示的此活动的描述。 + + + 关于此代理的角色和目的的描述。 + + + 此代理所需的服务列表 + + + 此 secret 的值 + + + 初始指令或上下文,用于定义Semantic Kernel代理如何生成内容。此模板指导代理的行为,并帮助它理解需要扮演的角色或执行的任务。 + + + 模型的温度。值越高,意味着模型将承担更大的风险。尝试0.1以获得与模型训练内容非常接近的结果。尝试0.9以获得极具创意的结果。 + + + 日志 + + + 基本元素 + + + 脚本语言 + + + 显示当前容器范围内的事件 + + + 显示相对时间 + + + 服务的设置以JSON格式表示。 + + + 系统提示模板,代理将使用该模板。 + + + 重复任何一个token的惩罚。更高的频率惩罚将减少token重复的可能性,促进更多样化的文本生成。 + + + secret的范围可以从下拉列表中筛选可用选项。 + + + 代码编辑器 + + + 下拉列表 + + + JSON编辑器 + + + 复选框列表 + + + 单选按钮列表 + + + 单行文本输入 + + + 复选框 + + + 当前作用域中已经存在这个名称的变量。 + + + 工作流定义选择器 + + + 工作流输出定义选择器 + + + 这个名称的输入已经存在。 + + + 您确定要删除选定的输入吗? + + + 您确定要删除选定的工作流吗? + + + 您确定要删除此版本吗? + + + 您确定要删除此工作流实例吗? + + + 确定取消正在运行的工作流实例? + + + 确定取消选定的工作流实例? + + + 复选框 + + + 创建变量 + + + 默认 + + + 确定删除选定的输入? + + + 确认删除选定的工作流实例? + + + 确定删除选定的工作流? + + + 编辑变量 + + + 输入将用于确定此属性的日志持久性策略的表达式。 + + + 导入 {0} 个工作流定义失败。错误:{1} + + + 导入成功。 + + + 继承 + + + 多行 + + + 多文本 + + + 未执行 + + + 无 + + + 不能作为活动使用。 + + + 一个使用已发布工作流的工作流已被更新 + + + 已经发布了一个工作流 + + + 输出选择器 + + + 请输入这个变量的名称。 + + + 请输入这个工作流的名称。 + + + 单行 + + + 导入成功 + + + 要在设计器中显示的文本。 + + + 时间戳 + + + 当选中时,此活动是此工作流的开始。 + + + 工作流定义选择器 + + + 工作流已发布 + + + 发布的工作流没有找到活动 + + + 工作流已撤销发布 + + + 已更新使用当前已发布工作流的其他工作流 + + + 删除版本 {0} + + + {0} 个工作流已发布 + + + 已更新 {0} 个使用已发布工作流的工作流 + + + {0} {1} 导入成功。 + + + 您确定要取消此工作流实例吗? + + + 没有找到要导入的工作流。 + + + 确定删除工作流? + + + 没有导入任何工作流。 + + + 多行文本输入 + + + 成功导入 1 个工作流定义。 + + + 删除版本 + + + 复选框列表 + + + 具有此名称的工作流已经存在。 + + + 您确定要删除选定的输出吗? + + + 无法启动工作流 + + + 创建输入 + + + 发布一个工作流 + + + 删除选定版本 + + + 发布选定的工作流? + + + 启动工作流成功 + + + 编辑输出 + + + 您确定要取消选定的工作流实例吗? + + + 您确定要删除此工作流吗? + + + 变量选择器 + + + 默认策略 + + + 代码编辑器 + + + 确定要取消此工作流定义的所有正在运行的工作流实例吗? + + + 您确定要发布选定的工作流吗? + + + 您确定要删除选定的变量吗? + + + 创建输出 + + + 确定删除工作流实例? + + + 结果选择器 + + + 您确定要删除选定的版本吗? + + + 多个单词的输入,如标记输入 + + + 您确定要删除选定的工作流实例吗? + + + 您确定要取消选定的工作流吗? + + + 确认删除选定的变量? + + + 请输入这个输出的名称。 + + + 取消工作流实例? + + + 编辑工作流定义 + + + 新工作流 + + + 没有找到一个工作流 + + + 确定删除选定的输出? + + + {0} 个使用中的工作流已更新 + + + 下拉 + + + 单选列表 + + + 消息 + + + 撤销发布一个工作流 + + + JSON 编辑器 + + + 请输入这个输入的名称。 + + + 工作流已经发布 + + + 结果选择器 + + + 一个工作流已经撤销发布 + + + 只读 + + + 成功导入一个实例 + + + 工作流定义。 + + + 显示描述 + + + 已撤销工作流 + + + 要使用的提交策略控制应何时该提交工作流状态。 + + + 变量的ID。 + + + 只读工作流不会受到影响。 + + + 上传包含工作流数据的JSON文件或包含工作流数据的JSON文件的压缩包(ZIP)导入。 + + + 变量选择器 + + + 确定取消发布选定的工作流? + + + 当被选中时,此活动可以触发此工作流。 + + + 已保存工作流 + + + 未找到工作流 + + + 工作流已经发布 + + + 成功导入 {0} 个实例 + + + 已取消发布工作流 + + + 工作流已撤销发布 + + + 工作流已发布 + + + {0} 个工作流已发布 + + + {0} {1} 导入失败。 + + + 成功导入 {0} 个工作流定义。 + + + {0} 个工作流已取消发布 + + + {0} 个工作流未找到 + + + {0} 个工作流已取消发布 + + + 连接模式决定这个活动是否应该在一个入站路径进入时就继续(等待任意一个),还是在所有入站路径都执行完毕后才继续(等待全部)。 + + + 用于分派工作流的数据源。 + + + 在将当前项发送到被分派的工作流时用于输入名称的默认键。如果Items字段包含字典列表,则不会使用该键 + + + 自动布局 + + + 中心 + + + 缩放适应屏幕 + + + 一个用来计算关联分发的工作流的相关性ID的函数。 + + + 一个预期结果列表进行处理。 + + + 一个要处理的预期状态码列表。 + + + 一个允许在不进行验证的情况下添加授权头的值。 + + + 始终允许创建 + + + 分支 + + + 跳出循环。 + + + 已取消 + + + 状态 + + + 内容形式 + + + 相关 ID 函数 + + + 默认项目输入键 + + + 禁用授权头验证 + + + 执行JavaScript代码 + + + 执行中 + + + 预期的状态码 + + + 方法 + + + 模式 + + + 请求内容。 + + + 结果 + + + 运行中 + + + 建议方法 + + + 和请求一起发送的授权头值。例如:Bearer {some - access - token} + + + 随请求发送的内容。可以是字符串、对象、字节数组或者流。 + + + 发送请求时使用的内容类型。 + + + 要分派的工作流的定义ID。 + + + 发送请求时使用的HTTP方法。 + + + 要接受的HTTP方法。 + + + 完成此活动的结果或结果集。 + + + 与工作流关联的路径。 + + + 切换模式决定是应该安排第一个匹配项,还是安排所有匹配项。 + + + 用于下载文件的URL。 + + + 持续时间 + + + 在未来特定的时间触发执行。 + + + URL + + + 验证结果 + + + 工作流定义 + + + 添加示例 + + + 数据 + + + 标签 + + + 结果 + + + 缩放匹配 + + + 总是允许创建新的工作流实例。 + + + 将当前值赋给指定的变量。 + + + 代码 + + + 控制结束步骤是包含还是排除上界/下界。默认为True(包含)。 + + + 现有赋值 + + + 间隔 + + + 包含外部边界 + + + 负载 + + + 步 + + + 终止步骤。 + + + 要迭代的项目。 + + + 要迭代的值集合。 + + + 初始化。 + + + 步长。要倒计时,请输入一个负数。 + + + 变量 + + \ No newline at end of file diff --git a/src/framework/Elsa.Studio.Translations/Translations.zh-Hant.resx b/src/framework/Elsa.Studio.Translations/Translations.zh-Hant.resx new file mode 100644 index 0000000..e6a3f64 --- /dev/null +++ b/src/framework/Elsa.Studio.Translations/Translations.zh-Hant.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 此代理的簡短描述。 + + + 90 天 + + + 14 天 + + + 180 天 + + + 30 天 + + + 7 天 + + + 此密鑰的簡短描述。 + + + 分配此流程為活動到自定義類別。 + + + 預設值。 + + + 此流程的簡短描述。 + + + 此輸出的簡短描述。 + + + 此輸入的簡短描述。 + + + 依輸出群組客製化分類。 + + + 角色描述及此代理的目的。 + + + 角色描述及此輸入變數的目的。 + + + 秘密描述 + + + 新增輸出 + + + 代理 + + + 新增變數 + + + 自動儲存 + + + 取消 + + + 類別 + + \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Components/BackendComponentBase.cs b/src/hosts/Elsa.Studio.Host.CustomElements/Components/BackendComponentBase.cs new file mode 100644 index 0000000..92e39c3 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Components/BackendComponentBase.cs @@ -0,0 +1,34 @@ +using Elsa.Studio.Components; +using Elsa.Studio.Host.CustomElements.Services; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Host.CustomElements.Components; + +public abstract class BackendComponentBase : StudioComponentBase +{ + [Parameter] public string? RemoteEndpoint { get; set; } + [Parameter] public string? ApiKey { get; set; } + [Parameter] public string? AccessToken { get; set; } + [Parameter] public string? TenantId { get; set; } + [Parameter] public string? TenantIdHeaderName { get; set; } + [Inject] private BackendService BackendService { get; set; } = null!; + + /// + protected override void OnInitialized() + { + if (!string.IsNullOrWhiteSpace(RemoteEndpoint)) + BackendService.RemoteEndpoint = RemoteEndpoint; + + if (!string.IsNullOrWhiteSpace(ApiKey)) + BackendService.ApiKey = ApiKey; + + if (!string.IsNullOrWhiteSpace(AccessToken)) + BackendService.AccessToken = AccessToken; + + if(!string.IsNullOrWhiteSpace(TenantId)) + BackendService.TenantId = TenantId; + + if(!string.IsNullOrWhiteSpace(TenantIdHeaderName)) + BackendService.TenantIdHeaderName = TenantIdHeaderName; + } +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Components/BackendProvider.razor b/src/hosts/Elsa.Studio.Host.CustomElements/Components/BackendProvider.razor new file mode 100644 index 0000000..3626fa6 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Components/BackendProvider.razor @@ -0,0 +1 @@ +@inherits BackendComponentBase \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Components/ThemedComponentWrapper.razor b/src/hosts/Elsa.Studio.Host.CustomElements/Components/ThemedComponentWrapper.razor new file mode 100644 index 0000000..39d3d75 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Components/ThemedComponentWrapper.razor @@ -0,0 +1,18 @@ +@using Elsa.Studio.Contracts +@inherits BackendComponentBase +@inject IThemeService ThemeService + + + + + +@ChildContent + +@code +{ + /// + /// The component to render. + /// + [Parameter] + public RenderFragment ChildContent { get; set; } = default!; +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowDefinitionEditorWrapper.razor b/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowDefinitionEditorWrapper.razor new file mode 100644 index 0000000..2f2a359 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowDefinitionEditorWrapper.razor @@ -0,0 +1,54 @@ +@using System.Text.Json.Nodes +@using Elsa.Api.Client.Resources.WorkflowDefinitions.Models +@inherits BackendComponentBase + + + + + +@code +{ + private bool _shouldRender; + private string _definitionId = default!; + + /// The ID of the workflow definition to edit. + [Parameter] public string DefinitionId + { + get => _definitionId; + set + { + if (_definitionId == value) return; + _definitionId = value; + _shouldRender = true; + } + } + + /// An event that is invoked when a workflow definition has been executed. + /// The ID of the workflow instance is provided as the value to the event callback. + [Parameter] public Func? WorkflowDefinitionExecuted { get; set; } + + /// Gets or sets the event that occurs when the workflow definition version is updated. + [Parameter] public Func? WorkflowDefinitionVersionSelected { get; set; } + + /// Gets or sets the event triggered when an activity is selected. + [Parameter] public Func? ActivitySelected { get; set; } + + /// Gets the currently selected activity ID. + public string? SelectedActivityId => WorkflowDefinitionEditor.SelectedActivityId; + + private WorkflowDefinitionEditor WorkflowDefinitionEditor { get; set; } = default!; + + /// Gets the currently selected workflow definition version. + public WorkflowDefinition? GetSelectedWorkflowDefinitionVersion() => WorkflowDefinitionEditor.GetSelectedWorkflowDefinitionVersion(); + + /// + protected override bool ShouldRender() + { + if (!_shouldRender) return false; + _shouldRender = false; + return true; + } +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowDefinitionListWrapper.razor b/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowDefinitionListWrapper.razor new file mode 100644 index 0000000..784acd6 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowDefinitionListWrapper.razor @@ -0,0 +1,13 @@ +@inherits BackendComponentBase + + + + + +@code +{ + /// + /// An event that is invoked when a workflow definition is edited. + /// + [Parameter] public EventCallback EditWorkflowDefinition { get; set; } +} diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowInstanceListWrapper.razor b/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowInstanceListWrapper.razor new file mode 100644 index 0000000..c8c6e32 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowInstanceListWrapper.razor @@ -0,0 +1,14 @@ +@inherits BackendComponentBase + + + + + +@code{ + + /// + /// An event that is invoked when a workflow instance is viewed. + /// + [Parameter] public EventCallback ViewWorkflowInstance { get; set; } + +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowInstanceViewerWrapper.razor b/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowInstanceViewerWrapper.razor new file mode 100644 index 0000000..b1d9db1 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Components/WorkflowInstanceViewerWrapper.razor @@ -0,0 +1,20 @@ +@inherits BackendComponentBase + + + + + +@code +{ + /// + /// The ID of the workflow definition to edit. + /// + [Parameter] + public string InstanceId { get; set; } = default!; + + /// + /// An event that is invoked when a workflow definition is edited. + /// + [Parameter] + public EventCallback EditWorkflowDefinition { get; set; } +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Elsa.Studio.Host.CustomElements.csproj b/src/hosts/Elsa.Studio.Host.CustomElements/Elsa.Studio.Host.CustomElements.csproj new file mode 100644 index 0000000..0918f0a --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Elsa.Studio.Host.CustomElements.csproj @@ -0,0 +1,32 @@ + + + + Linux + true + + + + + + + + + + + Always + + + + + + + + + + + + + + + + diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/HttpMessageHandlers/ApiKeyHttpMessageHandler.cs b/src/hosts/Elsa.Studio.Host.CustomElements/HttpMessageHandlers/ApiKeyHttpMessageHandler.cs new file mode 100644 index 0000000..74895b0 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/HttpMessageHandlers/ApiKeyHttpMessageHandler.cs @@ -0,0 +1,38 @@ +using Elsa.Studio.Host.CustomElements.Services; + +namespace Elsa.Studio.Host.CustomElements.HttpMessageHandlers; + +/// +/// An that configures the outgoing HTTP request to use the configured API key or bearer token. +/// +public class AuthHttpMessageHandler : DelegatingHandler +{ + private readonly BackendService _backendService; + + /// + /// Initializes a new instance of the class. + /// + public AuthHttpMessageHandler(BackendService backendService) + { + _backendService = backendService; + } + + /// + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var apiKey = _backendService.ApiKey; + var accessToken = _backendService.AccessToken; + var tenantId = _backendService.TenantId; + var tenantIdHeaderName = _backendService.TenantIdHeaderName; + + if(!string.IsNullOrEmpty(apiKey)) + request.Headers.Authorization = new("ApiKey", apiKey); + else if(!string.IsNullOrEmpty(accessToken)) + request.Headers.Authorization = new("Bearer", accessToken); + + if(!string.IsNullOrEmpty(tenantId)) + request.Headers.Add(tenantIdHeaderName, tenantId); + + return await base.SendAsync(request, cancellationToken); + } +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Program.cs b/src/hosts/Elsa.Studio.Host.CustomElements/Program.cs new file mode 100644 index 0000000..9cd2093 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Program.cs @@ -0,0 +1,69 @@ +using Elsa.Studio.Shell.Extensions; +using Elsa.Studio.Workflows.Extensions; +using Elsa.Studio.Contracts; +using Elsa.Studio.Core.BlazorWasm.Extensions; +using Elsa.Studio.Extensions; +using Elsa.Studio.Host.CustomElements.Components; +using Elsa.Studio.Host.CustomElements.HttpMessageHandlers; +using Elsa.Studio.Host.CustomElements.Services; +using Elsa.Studio.Localization.Time; +using Elsa.Studio.Localization.Time.Providers; +using Elsa.Studio.Localization.Models; +using Elsa.Studio.Localization.BlazorWasm.Extensions; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Designer.Extensions; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.DependencyInjection.Extensions; + +// Build the host. +var builder = WebAssemblyHostBuilder.CreateDefault(args); +var configuration = builder.Configuration; + +// Register the custom elements. +builder.RootComponents.RegisterCustomElsaStudioElements(); +builder.RootComponents.RegisterCustomElement("elsa-backend-provider"); +builder.RootComponents.RegisterCustomElement("elsa-workflow-definition-editor"); +builder.RootComponents.RegisterCustomElement("elsa-workflow-instance-viewer"); +builder.RootComponents.RegisterCustomElement("elsa-workflow-instance-list"); +builder.RootComponents.RegisterCustomElement("elsa-workflow-definition-list"); + +// Register local services. +builder.Services.AddSingleton(); + +// Register the modules. +var backendApiConfig = new BackendApiConfig +{ + ConfigureBackendOptions = options => configuration.GetSection("Backend").Bind(options), + ConfigureHttpClientBuilder = options => + { + options.ApiKey = configuration["Backend:ApiKey"]; + options.AuthenticationHandler = typeof(AuthHttpMessageHandler); + }, +}; + +var localizationConfig = new LocalizationConfig +{ + ConfigureLocalizationOptions = options => configuration.GetSection("Localization").Bind(options), +}; + +builder.Services.AddCore(); +builder.Services.AddShell(); +builder.Services.AddRemoteBackend(backendApiConfig); +builder.Services.Replace(ServiceDescriptor.Scoped()); +builder.Services.AddWorkflowsModule(); +builder.Services.AddLocalizationModule(localizationConfig); +builder.Services.AddScoped(); + +// Build the application. +var app = builder.Build(); + +await app.UseElsaLocalization(); + +// Run each startup task. +var startupTask = app.Services.GetServices(); +foreach (var task in startupTask) await task.ExecuteAsync(); + +// Run the application. +await app.RunAsync(); + diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Properties/launchSettings.json b/src/hosts/Elsa.Studio.Host.CustomElements/Properties/launchSettings.json new file mode 100644 index 0000000..5f30317 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:15721", + "sslPort": 44319 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5122", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7251;http://localhost:5122", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Services/BackendService.cs b/src/hosts/Elsa.Studio.Host.CustomElements/Services/BackendService.cs new file mode 100644 index 0000000..23f4481 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Services/BackendService.cs @@ -0,0 +1,65 @@ +namespace Elsa.Studio.Host.CustomElements.Services; + +/// +/// Represents a service for backend configuration and information management. +/// +/// +/// The class provides properties to manage backend connectivity, +/// including endpoint configuration, API key management, access token, and tenant identification. +/// It acts as a centralized configuration point for backend communication settings. +/// +public class BackendService +{ + /// + /// Gets or sets the remote endpoint URL for backend communication. + /// + /// + /// The RemoteEndpoint property specifies the base URL of the backend service that the application interacts with. + /// It is used as a key configuration for defining the remote backend's address and is essential for facilitating communication with the service. + /// This property is typically configured during application initialization or dynamically at runtime. + /// + public string RemoteEndpoint { get; set; } = null!; + + /// + /// Gets or sets the API key used for authenticating requests to the backend service. + /// + /// + /// The ApiKey property is used to supply authentication credentials in the form of an API key + /// when communicating with the backend service. It is typically included in the request headers to identify + /// and authorize the client. This property should hold a secure, non-empty value if API key-based authentication + /// is enabled for the backend. Configuring this property correctly is critical for ensuring authorized access + /// to backend resources. + /// + public string? ApiKey { get; set; } + + /// + /// Gets or sets the access token used for authentication in backend communication. + /// + /// + /// The AccessToken property specifies a bearer token used for authorizing requests to protected backend resources. + /// This property is typically set during initialization or dynamically updated to ensure proper authorization headers are sent with HTTP requests. + /// It is utilized when API key-based authentication is not provided, ensuring secure access through bearer token mechanisms. + /// + public string? AccessToken { get; set; } + + /// + /// Gets or sets the tenant identifier for backend communication. + /// + /// + /// The TenantId property specifies the unique identifier associated with the tenant context in the backend service. + /// It is used to distinguish resources and operations specific to a particular tenant, enabling multi-tenancy support. + /// This property can be set during initialization or dynamically altered at runtime to switch between tenants. + /// Setting this property is not necessary if the carries a claim that can be used on the back-end to determine the current tenant. + /// + public string? TenantId { get; set; } + + /// + /// Gets or sets the name of the HTTP header used for tenant identification during backend communication. + /// + /// + /// The TenantIdHeaderName property defines the header key that carries the tenant identifier in HTTP requests. + /// It is essential for multi-tenant applications to distinguish between different tenants while interacting with the backend service. + /// This property can be customized to align with specific header naming conventions required by the backend. + /// + public string TenantIdHeaderName { get; set; } = "X-Tenant-Id"; +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/Services/ComponentRemoteBackendAccessor.cs b/src/hosts/Elsa.Studio.Host.CustomElements/Services/ComponentRemoteBackendAccessor.cs new file mode 100644 index 0000000..161f8a2 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/Services/ComponentRemoteBackendAccessor.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.Options; +using Elsa.Studio.Services; + +namespace Elsa.Studio.Host.CustomElements.Services; + +/// +/// A default implementation of that uses the to determine the URL of the remote backend. +/// +public class ComponentRemoteBackendAccessor : IRemoteBackendAccessor +{ + private readonly BackendService _backendService; + + /// + /// Initializes a new instance of the class. + /// + public ComponentRemoteBackendAccessor(BackendService backendService) + { + _backendService = backendService; + } + + /// + public RemoteBackend RemoteBackend => new(new(_backendService.RemoteEndpoint)); +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/_Imports.razor b/src/hosts/Elsa.Studio.Host.CustomElements/_Imports.razor new file mode 100644 index 0000000..2d56cb6 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/_Imports.razor @@ -0,0 +1,9 @@ +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.JSInterop +@using MudBlazor +@using Elsa.Studio.Components +@using Elsa.Studio.Shell +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor +@using Elsa.Studio.Workflows.Components.WorkflowInstanceViewer +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionList +@using Elsa.Studio.Workflows.Components.WorkflowInstanceList \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/appsettings.Development.json b/src/hosts/Elsa.Studio.Host.CustomElements/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/appsettings.json b/src/hosts/Elsa.Studio.Host.CustomElements/appsettings.json new file mode 100644 index 0000000..7b8a827 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/appsettings.json @@ -0,0 +1,12 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Shell": { + "DisableAuthorization": false + } +} diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/npm/package.json b/src/hosts/Elsa.Studio.Host.CustomElements/npm/package.json new file mode 100644 index 0000000..22cf8be --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/npm/package.json @@ -0,0 +1,22 @@ +{ + "name": "@elsa-workflows/elsa-studio-wasm", + "version": "3.0.0-preview.1", + "description": "Provides Elsa Studio Blazor components wrapped as custom elements.", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "elsa workflows", + "blazor" + ], + "author": "Sipke Schoorstra", + "license": "MIT", + "files": [ + "_framework/*", + "_content/*", + "index.html", + "appsettings.json", + "Elsa.Studio.Host.CustomElements.styles.css" + ] + +} diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/wwwroot/appsettings.json b/src/hosts/Elsa.Studio.Host.CustomElements/wwwroot/appsettings.json new file mode 100644 index 0000000..c0c96b6 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/wwwroot/appsettings.json @@ -0,0 +1,11 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Backend": { + "Url": "https://localhost:5001/elsa/api" + } +} diff --git a/src/hosts/Elsa.Studio.Host.CustomElements/wwwroot/index.html b/src/hosts/Elsa.Studio.Host.CustomElements/wwwroot/index.html new file mode 100644 index 0000000..b38778e --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.CustomElements/wwwroot/index.html @@ -0,0 +1,43 @@ + + + + + + + MyApplication + + + + + + + + + + + + + + + + + + + + + +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + + + + + + + \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.HostedWasm/Elsa.Studio.Host.HostedWasm.csproj b/src/hosts/Elsa.Studio.Host.HostedWasm/Elsa.Studio.Host.HostedWasm.csproj new file mode 100644 index 0000000..53a53e3 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.HostedWasm/Elsa.Studio.Host.HostedWasm.csproj @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/hosts/Elsa.Studio.Host.HostedWasm/Middleware/WasmAssetsRewritingMiddleware.cs b/src/hosts/Elsa.Studio.Host.HostedWasm/Middleware/WasmAssetsRewritingMiddleware.cs new file mode 100644 index 0000000..d6ede90 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.HostedWasm/Middleware/WasmAssetsRewritingMiddleware.cs @@ -0,0 +1,63 @@ +namespace Elsa.Studio.Host.HostedWasm.Middleware; + +/// +/// Middleware that intercepts HTTP requests and rewrites specific asset-related paths +/// for Web Assembly applications to ensure proper routing and handling of static files. +/// +public class WasmAssetsRewritingMiddleware(RequestDelegate next, ILogger logger) +{ + private static readonly string[] TargetSegments = { "_content", "_framework" }; + + public async Task InvokeAsync(HttpContext context) + { + if (context.Request.Path.HasValue && NeedsRewriting(context.Request.Path.Value!)) + { + var path = context.Request.Path.Value!; + + // Call the private method to get the index of the target segment using spans + var segmentIndex = GetTargetSegmentIndex(path.AsSpan()); + + if (segmentIndex > 0) + { + // Use slices instead of Substring to avoid allocations + var newPath = path.AsSpan(segmentIndex).ToString(); // Convert back to a string only when required + context.Request.Path = newPath.StartsWith('/') ? newPath : $"/{newPath}"; + + if (logger.IsEnabled(LogLevel.Debug)) logger.LogDebug("Rewritten: {Path} -> {NewPath}", path, context.Request.Path.Value); + } + } + + // Call the next middleware in the pipeline + await next(context); + } + + private static bool NeedsRewriting(string path) + { + // Fast path: Return if the path does not include potential target segments + foreach (var segment in TargetSegments) + { + if (path.Contains(segment, StringComparison.OrdinalIgnoreCase)) + return true; + } + + return false; + } + + private static int GetTargetSegmentIndex(ReadOnlySpan path) + { + foreach (var segment in TargetSegments) + { + // Use Span instead of string concatenation and index search + var segmentAsSpan = $"{segment}/".AsSpan(); + var index = path.IndexOf(segmentAsSpan, StringComparison.OrdinalIgnoreCase); + + if (index >= 0) + { + return index; + } + } + + return -1; // No valid index found + } + +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.HostedWasm/Pages/_Host.cshtml b/src/hosts/Elsa.Studio.Host.HostedWasm/Pages/_Host.cshtml new file mode 100644 index 0000000..dd70def --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.HostedWasm/Pages/_Host.cshtml @@ -0,0 +1,79 @@ +@page "/" +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@inject IConfiguration Configuration; +@{ + var apiUrl = Configuration["Hosting:ApiUrl"]; + + // Get the first segment of the request path, which represents the tenant ID. + var segments = Request.Path.Value!.Split('/', StringSplitOptions.RemoveEmptyEntries); + var tenantId = segments.Length is 1 or > 2 ? segments[0] : null; + var baseRef = tenantId != null ? $"/{tenantId}/" : "/"; +} + + + + + + + + Elsa Studio 3 + + + + + + + + + + + + + + + + + + +
+
+
Loading...
+
+
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.HostedWasm/Program.cs b/src/hosts/Elsa.Studio.Host.HostedWasm/Program.cs new file mode 100644 index 0000000..15336e0 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.HostedWasm/Program.cs @@ -0,0 +1,43 @@ +using Elsa.Studio.Host.HostedWasm.Middleware; +using Microsoft.AspNetCore.StaticFiles; + +var builder = WebApplication.CreateBuilder(args); +builder.WebHost.UseStaticWebAssets(); + +// Add services to the container. +builder.Services.AddRazorPages(); +builder.Services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod())); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error", createScopeForErrors: true); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); +app.UseBlazorFrameworkFiles(); +app.UseRouting(); +app.UseCors(); + +// Insert this BEFORE UseStaticFiles middleware. +app.UseMiddleware(); + +// Use Static Files instead of MapStaticAssets. +app.UseStaticFiles(new StaticFileOptions +{ + ContentTypeProvider = new FileExtensionContentTypeProvider + { + Mappings = + { + // Add custom MIME type mappings for WASM + [".dat"] = "application/octet-stream" + } + } +}); +app.MapFallbackToPage("/_Host"); + +app.Run(); \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.HostedWasm/Properties/launchSettings.json b/src/hosts/Elsa.Studio.Host.HostedWasm/Properties/launchSettings.json new file mode 100644 index 0000000..e6da1c2 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.HostedWasm/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7267", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/hosts/Elsa.Studio.Host.HostedWasm/appsettings.Development.json b/src/hosts/Elsa.Studio.Host.HostedWasm/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.HostedWasm/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/hosts/Elsa.Studio.Host.HostedWasm/appsettings.json b/src/hosts/Elsa.Studio.Host.HostedWasm/appsettings.json new file mode 100644 index 0000000..d6c905b --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.HostedWasm/appsettings.json @@ -0,0 +1,12 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Hosting": { + "ApiUrl": "https://localhost:5001/elsa/api" + } +} diff --git a/src/hosts/Elsa.Studio.Host.Server/Dockerfile b/src/hosts/Elsa.Studio.Host.Server/Dockerfile new file mode 100644 index 0000000..c6b2265 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["Elsa.Studio.ServerApp/Elsa.Studio.ServerApp.csproj", "Elsa.Studio.ServerApp/"] +RUN dotnet restore "Elsa.Studio.ServerApp/Elsa.Studio.ServerApp.csproj" +COPY . . +WORKDIR "/src/Elsa.Studio.ServerApp" +RUN dotnet build "Elsa.Studio.ServerApp.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Elsa.Studio.ServerApp.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Elsa.Studio.ServerApp.dll"] diff --git a/src/hosts/Elsa.Studio.Host.Server/Elsa.Studio.Host.Server.csproj b/src/hosts/Elsa.Studio.Host.Server/Elsa.Studio.Host.Server.csproj new file mode 100644 index 0000000..0fb7355 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/Elsa.Studio.Host.Server.csproj @@ -0,0 +1,27 @@ + + + + Linux + + + + + .dockerignore + + + + + + + + + + + + + + + + + + diff --git a/src/hosts/Elsa.Studio.Host.Server/Pages/_Host.cshtml b/src/hosts/Elsa.Studio.Host.Server/Pages/_Host.cshtml new file mode 100644 index 0000000..00f8253 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/Pages/_Host.cshtml @@ -0,0 +1,56 @@ +@page "/" +@using Elsa.Studio.Shell +@using Microsoft.AspNetCore.Components.Web +@namespace Elsa.Studio.Host.Server.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers + + + + + + + + + + + + + + + + + + + + + + + + @* Use designer.v1.css for the old designer (and comment out the previous designer.css style reference).*@ + @* *@ + + + + + + + +
+ + An error has occurred. This application may no longer respond until reloaded. + + + An unhandled exception has occurred. See browser dev tools for details. + + Reload + 🗙 +
+ + + + + + + + + \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.Server/Program.cs b/src/hosts/Elsa.Studio.Host.Server/Program.cs new file mode 100644 index 0000000..181fcb0 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/Program.cs @@ -0,0 +1,122 @@ +using Elsa.Studio.Core.BlazorServer.Extensions; +using Elsa.Studio.Dashboard.Extensions; +using Elsa.Studio.Extensions; +using Elsa.Studio.Localization.Time; +using Elsa.Studio.Localization.Time.Providers; +using Elsa.Studio.Login.BlazorServer.Extensions; +using Elsa.Studio.Login.HttpMessageHandlers; +using Elsa.Studio.Models; +using Elsa.Studio.Secrets; +using Elsa.Studio.Shell.Extensions; +using Elsa.Studio.Webhooks.Extensions; +using Elsa.Studio.Workflows.Extensions; +using Elsa.Studio.Workflows.Designer.Extensions; +using Elsa.Studio.Localization.BlazorServer.Extensions; +using Elsa.Studio.Localization.Models; +using Elsa.Studio.Localization.Options; +using Elsa.Studio.Translations; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Elsa.Studio.Branding; +using Elsa.Studio.Host.Server; +using Elsa.Studio.Login.Extensions; + +// Build the host. +var builder = WebApplication.CreateBuilder(args); +var configuration = builder.Configuration; + +// Register Razor services. +builder.Services.AddRazorPages(); +builder.Services.AddServerSideBlazor(options => +{ + // Register the root components. + // V2 activity wrapper by default. + options.RootComponents.RegisterCustomElsaStudioElements(); + + // To use V1 activity wrapper layout, specify the V1 component instead: + //options.RootComponents.RegisterCustomElsaStudioElements(typeof(Elsa.Studio.Workflows.Designer.Components.ActivityWrappers.V1.EmbeddedActivityWrapper)); + + options.RootComponents.MaxJSRootComponents = 1000; +}); + +// Register shell services and modules. +var backendApiConfig = new BackendApiConfig +{ + ConfigureBackendOptions = options => configuration.GetSection("Backend").Bind(options), + ConfigureHttpClientBuilder = options => + { + options.AuthenticationHandler = typeof(AuthenticatingApiHttpMessageHandler); + options.ConfigureHttpClient = (_, client) => + { + // Set a long time out to simplify debugging both Elsa Studio and the Elsa Server backend. + client.Timeout = TimeSpan.FromHours(1); + }; + }, +}; + +var localizationConfig = new LocalizationConfig +{ + ConfigureLocalizationOptions = options => + { + configuration.GetSection(LocalizationOptions.LocalizationSection).Bind(options); + options.SupportedCultures = new[] { options?.DefaultCulture ?? new LocalizationOptions().DefaultCulture } + .Concat(options?.SupportedCultures.Where(culture => culture != options?.DefaultCulture) ?? []) .ToArray(); + } +}; + +builder.Services.AddScoped(); +builder.Services.AddCore().Replace(new(typeof(IBrandingProvider), typeof(StudioBrandingProvider), ServiceLifetime.Scoped)); +builder.Services.AddShell(options => configuration.GetSection("Shell").Bind(options)); +builder.Services.AddRemoteBackend(backendApiConfig); +builder.Services.AddLoginModule(); +builder.Services.UseElsaIdentity(); +// builder.Services.UseOAuth2(options => +// { +// options.ClientId = "ElsaStudio"; +// options.TokenEndpoint = "https://localhost:44366/connect/token"; +// options.Scope = "YourSite offline_access"; +// }); +builder.Services.AddDashboardModule(); +builder.Services.AddWorkflowsModule(); +builder.Services.AddWebhooksModule(); +builder.Services.AddSecretsModule(backendApiConfig); +builder.Services.AddLocalizationModule(localizationConfig); +builder.Services.AddTranslations(); + +// Replace some services with other implementations. +builder.Services.AddScoped(); + +// Uncomment for V1 designer theme (default is V2). +// builder.Services.Configure(options => +// { +// options.DesignerCssClass = "elsa-flowchart-diagram-designer-v1"; +// options.GraphSettings.Grid.Type = "mesh"; +// }); + +// Configure SignalR. +builder.Services.AddSignalR(options => +{ + // Set MaximumReceiveMessageSize: + options.MaximumReceiveMessageSize = 5 * 1024 * 1000; // 5MB +}); + +// Build the application. +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseResponseCompression(); + + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseElsaLocalization(); +app.UseHttpsRedirection(); +app.UseStaticFiles(); +app.UseRouting(); +app.UseAuthorization(); +app.MapControllers(); +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); +app.Run(); \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.Server/Properties/launchSettings.json b/src/hosts/Elsa.Studio.Host.Server/Properties/launchSettings.json new file mode 100644 index 0000000..65b29fc --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/Properties/launchSettings.json @@ -0,0 +1,35 @@ +{ + "iisSettings": { + "iisExpress": { + "applicationUrl": "http://localhost:50413", + "sslPort": 44382 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5010", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7113;http://localhost:5010", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/hosts/Elsa.Studio.Host.Server/StudioBrandingProvider.cs b/src/hosts/Elsa.Studio.Host.Server/StudioBrandingProvider.cs new file mode 100644 index 0000000..abfd026 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/StudioBrandingProvider.cs @@ -0,0 +1,10 @@ +using Elsa.Studio.Branding; + +namespace Elsa.Studio.Host.Server +{ + /// + public class StudioBrandingProvider : DefaultBrandingProvider + { + public override string AppName => "Elsa Studio 3.5"; + } +} \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.Server/_Imports.razor b/src/hosts/Elsa.Studio.Host.Server/_Imports.razor new file mode 100644 index 0000000..2ae3b36 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/_Imports.razor @@ -0,0 +1,5 @@ +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Mvc.TagHelpers +@using Microsoft.JSInterop \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.Server/appsettings.Development.json b/src/hosts/Elsa.Studio.Host.Server/appsettings.Development.json new file mode 100644 index 0000000..770d3e9 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "DetailedErrors": true, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/hosts/Elsa.Studio.Host.Server/appsettings.json b/src/hosts/Elsa.Studio.Host.Server/appsettings.json new file mode 100644 index 0000000..b61e9c9 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Server/appsettings.json @@ -0,0 +1,22 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Shell": { + "DisableAuthorization": false + }, + "Backend": { + "Url": "https://localhost:5001/elsa/api" + }, + "Localization": { + "DefaultCulture": "fa-IR", + "SupportedCultures": [ + "fa-IR", + "en-US" + ] + } +} diff --git a/src/hosts/Elsa.Studio.Host.Wasm/Dockerfile b/src/hosts/Elsa.Studio.Host.Wasm/Dockerfile new file mode 100644 index 0000000..d0565b4 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Wasm/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["src/Elsa.Studio.WebAssemblyApp/Elsa.Studio.WebAssemblyApp.csproj", "src/Elsa.Studio.WebAssemblyApp/"] +RUN dotnet restore "src/Elsa.Studio.WebAssemblyApp/Elsa.Studio.WebAssemblyApp.csproj" +COPY . . +WORKDIR "/src/src/Elsa.Studio.WebAssemblyApp" +RUN dotnet build "Elsa.Studio.WebAssemblyApp.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Elsa.Studio.WebAssemblyApp.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Elsa.Studio.WebAssemblyApp.dll"] diff --git a/src/hosts/Elsa.Studio.Host.Wasm/Elsa.Studio.Host.Wasm.csproj b/src/hosts/Elsa.Studio.Host.Wasm/Elsa.Studio.Host.Wasm.csproj new file mode 100644 index 0000000..dc46208 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Wasm/Elsa.Studio.Host.Wasm.csproj @@ -0,0 +1,30 @@ + + + + Linux + true + + + + + + + + + + + Always + + + + + + + + + + + + + + diff --git a/src/hosts/Elsa.Studio.Host.Wasm/Program.cs b/src/hosts/Elsa.Studio.Host.Wasm/Program.cs new file mode 100644 index 0000000..0a5d08c --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Wasm/Program.cs @@ -0,0 +1,63 @@ +using Elsa.Studio.Dashboard.Extensions; +using Elsa.Studio.Shell; +using Elsa.Studio.Shell.Extensions; +using Elsa.Studio.Workflows.Extensions; +using Elsa.Studio.Contracts; +using Elsa.Studio.Core.BlazorWasm.Extensions; +using Elsa.Studio.Extensions; +using Elsa.Studio.Localization.Time; +using Elsa.Studio.Localization.Time.Providers; +using Elsa.Studio.Login.BlazorWasm.Extensions; +using Elsa.Studio.Login.HttpMessageHandlers; +using Elsa.Studio.Models; +using Elsa.Studio.WorkflowContexts.Extensions; +using Elsa.Studio.Workflows.Designer.Extensions; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Elsa.Studio.Localization.Models; +using Elsa.Studio.Localization.BlazorWasm.Extensions; + +// Build the host. +var builder = WebAssemblyHostBuilder.CreateDefault(args); +var configuration = builder.Configuration; + +// Register root components. +builder.RootComponents.Add("#app"); +builder.RootComponents.Add("head::after"); +builder.RootComponents.RegisterCustomElsaStudioElements(); + +// Register shell services and modules. +var backendApiConfig = new BackendApiConfig +{ + ConfigureBackendOptions = options => configuration.GetSection("Backend").Bind(options), + ConfigureHttpClientBuilder = options => options.AuthenticationHandler = typeof(AuthenticatingApiHttpMessageHandler), +}; + +var localizationConfig = new LocalizationConfig +{ + ConfigureLocalizationOptions = options => configuration.GetSection("Localization").Bind(options), +}; + +builder.Services.AddCore(); +builder.Services.AddShell(); +builder.Services.AddRemoteBackend(backendApiConfig); +builder.Services.AddLoginModule(); +builder.Services.AddDashboardModule(); +builder.Services.AddWorkflowsModule(); +builder.Services.AddWorkflowContextsModule(); +builder.Services.AddLocalizationModule(localizationConfig); + +// Replace some services with other implementations. +builder.Services.AddScoped(); + +// Build the application. +var app = builder.Build(); + +await app.UseElsaLocalization(); + +// Run each startup task. +var startupTaskRunner = app.Services.GetRequiredService(); +await startupTaskRunner.RunStartupTasksAsync(); + +// Run the application. +await app.RunAsync(); \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.Wasm/Properties/launchSettings.json b/src/hosts/Elsa.Studio.Host.Wasm/Properties/launchSettings.json new file mode 100644 index 0000000..c86a17a --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Wasm/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "iisSettings": { + "iisExpress": { + "applicationUrl": "http://localhost:10111", + "sslPort": 44341 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "http://localhost:5275", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "https://localhost:7052;http://localhost:5275", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/hosts/Elsa.Studio.Host.Wasm/_Imports.razor b/src/hosts/Elsa.Studio.Host.Wasm/_Imports.razor new file mode 100644 index 0000000..a2fe699 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Wasm/_Imports.razor @@ -0,0 +1,6 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.WebAssembly.Http +@using Microsoft.JSInterop \ No newline at end of file diff --git a/src/hosts/Elsa.Studio.Host.Wasm/wwwroot/appsettings.json b/src/hosts/Elsa.Studio.Host.Wasm/wwwroot/appsettings.json new file mode 100644 index 0000000..c0c96b6 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Wasm/wwwroot/appsettings.json @@ -0,0 +1,11 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Backend": { + "Url": "https://localhost:5001/elsa/api" + } +} diff --git a/src/hosts/Elsa.Studio.Host.Wasm/wwwroot/index.html b/src/hosts/Elsa.Studio.Host.Wasm/wwwroot/index.html new file mode 100644 index 0000000..b9f2c44 --- /dev/null +++ b/src/hosts/Elsa.Studio.Host.Wasm/wwwroot/index.html @@ -0,0 +1,47 @@ + + + + + + + Elsa Studio 3.5 + + + + + + + + + + + + + + + + + + + +
+
+
Loading...
+
+
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/Elsa.Studio.ActivityPortProviders.csproj b/src/modules/Elsa.Studio.ActivityPortProviders/Elsa.Studio.ActivityPortProviders.csproj new file mode 100644 index 0000000..6a098aa --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/Elsa.Studio.ActivityPortProviders.csproj @@ -0,0 +1,13 @@ + + + + Provides various port providers for activities such as `FlowSwitch` and `SendHttpRequest`. + elsa studio module + + + + + + + + diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.ActivityPortProviders/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..92e7c53 --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,26 @@ +using Elsa.Studio.ActivityPortProviders.Providers; +using Elsa.Studio.Workflows.Extensions; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.ActivityPortProviders.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds default activity port providers. + /// + public static IServiceCollection AddDefaultActivityPortProviders(this IServiceCollection services) + { + services.AddActivityPortProvider(); + services.AddActivityPortProvider(); + services.AddActivityPortProvider(); + services.AddActivityPortProvider(); + services.AddActivityPortProvider(); + services.AddActivityPortProvider(); + + return services; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/FodyWeavers.xml b/src/modules/Elsa.Studio.ActivityPortProviders/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/FodyWeavers.xsd b/src/modules/Elsa.Studio.ActivityPortProviders/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/Providers/DynamicOutcomesPortProvider.cs b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/DynamicOutcomesPortProvider.cs new file mode 100644 index 0000000..3af1eb7 --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/DynamicOutcomesPortProvider.cs @@ -0,0 +1,96 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Providers; +using Humanizer; + +namespace Elsa.Studio.ActivityPortProviders.Providers; + +/// +/// Provides ports for the FlowSendHttpRequest activity based on its supported status codes. +/// +public class DynamicOutcomesPortProvider : ActivityPortProviderBase +{ + /// + public override bool GetSupportsActivityType(PortProviderContext context) => GetDynamicOutcomesInput(context) != null; + + /// + public override IEnumerable GetPorts(PortProviderContext context) + { + var dynamicOutcomesInputDescriptor = GetDynamicOutcomesInput(context)!; + var dynamicOutcomes = GetDynamicOutcomes(context.Activity, dynamicOutcomesInputDescriptor).ToList(); + + foreach (var dynamicOutcome in dynamicOutcomes) + { + yield return new Port + { + Name = dynamicOutcome, + Type = PortType.Flow, + DisplayName = dynamicOutcome + }; + } + + var dynamicOutcomesOptions = GetDynamicOutcomeOptions(dynamicOutcomesInputDescriptor); + var fixedOutcomes = dynamicOutcomesOptions?.FixedOutcomes; + + if (fixedOutcomes == null) + yield break; + + foreach (var outcome in fixedOutcomes) + { + yield return new Port + { + Name = outcome, + Type = PortType.Flow, + DisplayName = outcome + }; + } + } + + private static DynamicOutcomesOptions? GetDynamicOutcomeOptions(InputDescriptor dynamicOutcomesInputDescriptor) + { + if (dynamicOutcomesInputDescriptor.UISpecifications?.TryGetValue(nameof(DynamicOutcomesOptions), out var dynamicOutcomesOptions) != true) + return default; + + var serializerOptions = CreateSerializerOptions(); + var options = ((JsonElement)dynamicOutcomesOptions!).Deserialize(serializerOptions); + + return options; + + } + + private static InputDescriptor? GetDynamicOutcomesInput(PortProviderContext context) + { + return context.ActivityDescriptor.Inputs.FirstOrDefault(x => x.UIHint == "dynamic-outcomes"); + } + + private static IEnumerable GetDynamicOutcomes(JsonObject activity, PropertyDescriptor dynamicOutcomesInputDescriptor) + { + var options = CreateSerializerOptions(); + var dynamicOutcomesInputPropertyName = dynamicOutcomesInputDescriptor.Name.Camelize(); + + var wrappedInput = activity.GetProperty(options, dynamicOutcomesInputPropertyName) ?? new WrappedInput + { + TypeName = dynamicOutcomesInputDescriptor.TypeName, + Expression = Expression.CreateObject("[]") + }; + + var objectExpression = wrappedInput.Expression; + return JsonSerializer.Deserialize>(objectExpression.Value!.ToString()!, options)!; + } + + private static JsonSerializerOptions CreateSerializerOptions() + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + return options; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/Providers/FlowHttpRequestPortProvider.cs b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/FlowHttpRequestPortProvider.cs new file mode 100644 index 0000000..a25066b --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/FlowHttpRequestPortProvider.cs @@ -0,0 +1,97 @@ +using System.Net; +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Converters; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Providers; +using JetBrains.Annotations; + +namespace Elsa.Studio.ActivityPortProviders.Providers; + +/// +/// Provides ports for the FlowSendHttpRequest & DownloadHttpFile activities based on its supported status codes. +/// +[UsedImplicitly] +public class FlowHttpRequestPortProvider : ActivityPortProviderBase +{ + /// + public override bool GetSupportsActivityType(PortProviderContext context) + { + return context.ActivityDescriptor.TypeName is "Elsa.FlowSendHttpRequest" or "Elsa.DownloadHttpFile"; + } + + /// + public override IEnumerable GetPorts(PortProviderContext context) + { + var expectedStatusCodes = GetExpectedStatusCodes(context.Activity); + + foreach (var statusCode in expectedStatusCodes) + { + yield return new Port + { + Name = statusCode.ToString(), + Type = PortType.Flow, + DisplayName = statusCode.ToString() + }; + } + + yield return new Port + { + Name = "Unmatched status code", + Type = PortType.Flow, + DisplayName = "Unmatched status code" + }; + + yield return new Port + { + Name = "Failed to connect", + Type = PortType.Flow, + DisplayName = "Failed to connect" + }; + + yield return new Port + { + Name = "Timeout", + Type = PortType.Flow, + DisplayName = "Timeout" + }; + + yield return new Port + { + Name = "Done", + Type = PortType.Flow, + DisplayName = "Done" + }; + } + + private static IEnumerable GetExpectedStatusCodes(JsonObject activity) + { + var options = CreateSerializerOptions(); + + var wrappedInput = activity.GetProperty(options, "expectedStatusCodes") ?? new WrappedInput + { + TypeName = typeof(int[]).Name, + Expression = Expression.CreateObject(JsonSerializer.Serialize(new[] { (int)HttpStatusCode.OK }, options)) + }; + + var objectExpression = wrappedInput.Expression; + return JsonSerializer.Deserialize>(objectExpression.Value!.ToString()!, options)!; + } + + private static JsonSerializerOptions CreateSerializerOptions() + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + options.Converters.Add(new JsonStringToIntConverter()); + + return options; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/Providers/FlowSwitchPortProvider.cs b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/FlowSwitchPortProvider.cs new file mode 100644 index 0000000..2f96625 --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/FlowSwitchPortProvider.cs @@ -0,0 +1,51 @@ +using System.Text.Json; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Providers; +using JetBrains.Annotations; + +namespace Elsa.Studio.ActivityPortProviders.Providers; + +/// +/// Provides ports for the FlowSwitch activity based on its cases. +/// +[UsedImplicitly] +public class FlowSwitchPortProvider : ActivityPortProviderBase +{ + /// + public override bool GetSupportsActivityType(PortProviderContext context) => context.ActivityDescriptor.TypeName is "Elsa.FlowSwitch"; + + /// + public override IEnumerable GetPorts(PortProviderContext context) + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + var cases = context.Activity.GetProperty>(options, "cases") ?? new List(); + + foreach (var @case in cases) + { + yield return new Port + { + Name = @case.Label, + DisplayName = @case.Label, + Type = PortType.Flow, + }; + } + + if (cases.Any(x => x.Label == "Default")) + yield break; + + yield return new Port + { + Name = "Default", + DisplayName = "Default", + Type = PortType.Flow + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/Providers/HttpEndpointPortProvider.cs b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/HttpEndpointPortProvider.cs new file mode 100644 index 0000000..059f71e --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/HttpEndpointPortProvider.cs @@ -0,0 +1,52 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Providers; + +namespace Elsa.Studio.ActivityPortProviders.Providers; + +/// +/// Provides ports for the HttpEndpoint activity based on its configuration. +/// +public class HttpEndpointPortProvider : ActivityPortProviderBase +{ + private const string Done = "Done"; + private const string FileTooLarge = "File too large"; + private const string RequestTooLarge = "Request too large"; + private const string InvalidFileExtension = "Invalid file extension"; + private const string InvalidMimeType = "Invalid file MIME type"; + + /// + public override bool GetSupportsActivityType(PortProviderContext context) => context.ActivityDescriptor.TypeName is "Elsa.HttpEndpoint"; + + /// + public override IEnumerable GetPorts(PortProviderContext context) + { + if (ExposeFileTooLargeOutcome(context.Activity)) yield return CreatePort(FileTooLarge); + if (ExposeRequestTooLargeOutcome(context.Activity)) yield return CreatePort(RequestTooLarge); + if (ExposeInvalidFileExtensionOutcome(context.Activity)) yield return CreatePort(InvalidFileExtension); + if (ExposeInvalidFileMimeTypeOutcome(context.Activity)) yield return CreatePort(InvalidMimeType); + yield return CreatePort(Done); + } + + private bool ExposeFileTooLargeOutcome(JsonObject @case) => TryGetValue(@case, "exposeFileTooLargeOutcome", () => false); + private bool ExposeRequestTooLargeOutcome(JsonObject @case) => TryGetValue(@case, "exposeRequestTooLargeOutcome", () => false); + private bool ExposeInvalidFileExtensionOutcome(JsonObject @case) => TryGetValue(@case, "exposeInvalidFileExtensionOutcome", () => false); + private bool ExposeInvalidFileMimeTypeOutcome(JsonObject @case) => TryGetValue(@case, "exposeInvalidFileMimeTypeOutcome", () => false); + + private Port CreatePort(string name) + { + return new Port + { + Name = name, + DisplayName = name, + Type = PortType.Flow, + }; + } + + private static T TryGetValue(JsonObject model, string propName, Func defaultValue) + { + return model.TryGetPropertyValue(propName, out var node) ? node != null ? node.GetValue() : defaultValue() : defaultValue(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/Providers/SendHttpRequestPortProvider.cs b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/SendHttpRequestPortProvider.cs new file mode 100644 index 0000000..2c3cfd2 --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/SendHttpRequestPortProvider.cs @@ -0,0 +1,110 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Providers; + +namespace Elsa.Studio.ActivityPortProviders.Providers; + +/// +/// Provides ports for the FlowSendHttpRequest activity based on its supported status codes. +/// +public class SendHttpRequestPortProvider : ActivityPortProviderBase +{ + private const string UnmatchedStatusCodePortName = "Unmatched status code"; + + /// + public override bool GetSupportsActivityType(PortProviderContext context) => context.ActivityDescriptor.TypeName is "Elsa.SendHttpRequest"; + + /// + public override IEnumerable GetPorts(PortProviderContext context) + { + var cases = GetExpectedStatusCodes(context.Activity); + + foreach (var @case in cases) + { + var statusCode = GetStatusCode(@case); + + yield return new Port + { + Name = statusCode.ToString(), + DisplayName = statusCode.ToString(), + Type = PortType.Embedded, + }; + } + + yield return new Port + { + Name = UnmatchedStatusCodePortName, + DisplayName = "Unmatched status code", + Type = PortType.Embedded, + }; + } + + /// + public override JsonObject? ResolvePort(string portName, PortProviderContext context) + { + if (portName == UnmatchedStatusCodePortName) + return GetUnmatchedStatusCodeActivity(context.Activity); + + var cases = GetExpectedStatusCodes(context.Activity); + var @case = cases.FirstOrDefault(x => GetStatusCode(x).ToString() == portName); + + return GetActivity(@case); + } + + /// + public override void AssignPort(string portName, JsonObject activity, PortProviderContext context) + { + var switchActivity = context.Activity; + + if (portName == UnmatchedStatusCodePortName) + { + SetUnmatchedStatusCodeActivity(switchActivity, activity); + return; + } + + var cases = GetExpectedStatusCodes(switchActivity).ToList(); + var @case = cases.FirstOrDefault(x => GetStatusCode(x).ToString() == portName); + + if (@case == null) + return; + + SetActivity(@case, activity); + } + + /// + public override void ClearPort(string portName, PortProviderContext context) + { + if (portName == UnmatchedStatusCodePortName) + { + SetUnmatchedStatusCodeActivity(context.Activity, null); + return; + } + + var cases = GetExpectedStatusCodes(context.Activity).ToList(); + var @case = cases.FirstOrDefault(x => GetStatusCode(x).ToString() == portName); + + if (@case == null) + return; + + SetActivity(@case, null); + } + + private static IEnumerable GetExpectedStatusCodes(JsonObject switchActivity) + { + return switchActivity.GetProperty("expectedStatusCodes")?.AsArray().AsEnumerable().Cast() ?? new List(); + } + + private static void SetExpectedStatusCodes(JsonObject switchActivity, ICollection cases) + { + switchActivity.SetProperty(cases, "expectedStatusCodes"); + } + + private int GetStatusCode(JsonObject @case) => @case.GetProperty("statusCode")!.GetValue(); + private JsonObject? GetActivity(JsonObject? @case) => @case?.GetProperty("activity")?.AsObject(); + private void SetActivity(JsonObject @case, JsonObject? activity) => @case.SetProperty(activity, "activity"); + private JsonObject? GetUnmatchedStatusCodeActivity(JsonObject httpRequestActivity) => httpRequestActivity.GetProperty("unmatchedStatusCode")?.AsObject(); + private void SetUnmatchedStatusCodeActivity(JsonObject httpRequestActivity, JsonObject? activity) => httpRequestActivity.SetProperty(activity, "unmatchedStatusCode"); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.ActivityPortProviders/Providers/SwitchPortProvider.cs b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/SwitchPortProvider.cs new file mode 100644 index 0000000..e0dd624 --- /dev/null +++ b/src/modules/Elsa.Studio.ActivityPortProviders/Providers/SwitchPortProvider.cs @@ -0,0 +1,103 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Providers; + +namespace Elsa.Studio.ActivityPortProviders.Providers; + +/// +/// Provides ports for the Switch activity based on its cases. +/// +public class SwitchPortProvider : ActivityPortProviderBase +{ + /// + public override bool GetSupportsActivityType(PortProviderContext context) => context.ActivityDescriptor.TypeName == "Elsa.Switch"; + + /// + public override IEnumerable GetPorts(PortProviderContext context) + { + var cases = GetCases(context.Activity).ToList(); + + foreach (var @case in cases) + { + var label = GetLabel(@case); + yield return new Port + { + Name = label, + DisplayName = label, + Type = PortType.Embedded, + }; + } + + if (cases.Any(x => GetLabel(x) == "Default")) + yield break; + + yield return new Port + { + Name = "Default", + DisplayName = "Default", + Type = PortType.Embedded + }; + } + + /// + public override JsonObject? ResolvePort(string portName, PortProviderContext context) + { + if (portName == "Default") + { + return context.Activity.GetProperty("default"); + } + + var cases = GetCases(context.Activity); + var @case = cases.FirstOrDefault(x => GetLabel(x) == portName); + + return @case != null ? GetActivity(@case) : null; + } + + /// + public override void AssignPort(string portName, JsonObject activity, PortProviderContext context) + { + if(portName == "Default") + { + context.Activity.SetProperty(activity, "default"); + return; + } + + var cases = GetCases(context.Activity).ToList(); + var @case = cases.FirstOrDefault(x => GetLabel(x) == portName); + + if (@case == null) + return; + + SetActivity(@case, activity); + } + + /// + public override void ClearPort(string portName, PortProviderContext context) + { + if(portName == "Default") + { + context.Activity.SetProperty(null, "default"); + return; + } + + var cases = GetCases(context.Activity).ToList(); + var @case = cases.FirstOrDefault(x => GetLabel(x) == portName); + + if (@case == null) + return; + + SetActivity(@case, null); + } + + private string GetLabel(JsonObject @case) => @case.GetProperty("label")?.GetValue()!; + private JsonObject? GetActivity(JsonObject @case) => @case.GetProperty("activity")?.AsObject(); + private void SetActivity(JsonObject @case, JsonObject? activity) => @case.SetProperty(activity, "activity"); + + private static IEnumerable GetCases(JsonObject switchActivity) + { + return switchActivity.GetProperty("cases")?.AsArray().AsEnumerable().Cast() ?? new List(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Counter/Elsa.Studio.Counter.csproj b/src/modules/Elsa.Studio.Counter/Elsa.Studio.Counter.csproj new file mode 100644 index 0000000..769ba34 --- /dev/null +++ b/src/modules/Elsa.Studio.Counter/Elsa.Studio.Counter.csproj @@ -0,0 +1,16 @@ + + + + Adds the classical Counter screen from the default Blazor template to the studio. + elsa studio module + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Counter/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Counter/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..560ff21 --- /dev/null +++ b/src/modules/Elsa.Studio.Counter/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,17 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Counter.Menu; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Counter.Extensions; + +/// Extension methods to add the Counter module to the service collection. +public static class ServiceCollectionExtensions +{ + /// Adds the Counter module to the service collection. + public static IServiceCollection AddCounterModule(this IServiceCollection services) + { + return services + .AddScoped() + .AddScoped(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Counter/FodyWeavers.xml b/src/modules/Elsa.Studio.Counter/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Counter/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Counter/FodyWeavers.xsd b/src/modules/Elsa.Studio.Counter/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Counter/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Counter/Menu/CounterMenu.cs b/src/modules/Elsa.Studio.Counter/Menu/CounterMenu.cs new file mode 100644 index 0000000..55f8143 --- /dev/null +++ b/src/modules/Elsa.Studio.Counter/Menu/CounterMenu.cs @@ -0,0 +1,37 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using MudBlazor; + +namespace Elsa.Studio.Counter.Menu; + +public class CounterMenu : IMenuProvider +{ + public ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default) + { + var menuItems = new List + { + new() + { + Icon = Icons.Material.Filled.Add, + Href = "counter", + Text = "Counter", + GroupName = MenuItemGroups.General.Name, + SubMenuItems = new List + { + new() + { + Href = "counter", + Text = "Sub menu item 1", + }, + new() + { + Href = "counter2", + Text = "Sub menu item 2", + }, + } + } + }; + + return new ValueTask>(menuItems); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Counter/Module.cs b/src/modules/Elsa.Studio.Counter/Module.cs new file mode 100644 index 0000000..bc6c437 --- /dev/null +++ b/src/modules/Elsa.Studio.Counter/Module.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Abstractions; + +namespace Elsa.Studio.Counter; + +public class Feature : FeatureBase +{ + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Counter/Pages/Counter.razor b/src/modules/Elsa.Studio.Counter/Pages/Counter.razor new file mode 100644 index 0000000..a32f008 --- /dev/null +++ b/src/modules/Elsa.Studio.Counter/Pages/Counter.razor @@ -0,0 +1,19 @@ +@page "/counter" + +Counter + + + + Current count: @_currentCount + Click me + + + +@code { + private int _currentCount = 0; + + private void IncrementCount() + { + _currentCount++; + } +} diff --git a/src/modules/Elsa.Studio.Counter/_Imports.razor b/src/modules/Elsa.Studio.Counter/_Imports.razor new file mode 100644 index 0000000..418389e --- /dev/null +++ b/src/modules/Elsa.Studio.Counter/_Imports.razor @@ -0,0 +1,7 @@ +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.JSInterop +@using Elsa.Studio.Components +@using MudBlazor +@attribute [Authorize] \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Dashboard/Elsa.Studio.Dashboard.csproj b/src/modules/Elsa.Studio.Dashboard/Elsa.Studio.Dashboard.csproj new file mode 100644 index 0000000..725cd50 --- /dev/null +++ b/src/modules/Elsa.Studio.Dashboard/Elsa.Studio.Dashboard.csproj @@ -0,0 +1,17 @@ + + + + Adds a dashboard page to the studio. + elsa studio module + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Dashboard/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Dashboard/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..5d3c765 --- /dev/null +++ b/src/modules/Elsa.Studio.Dashboard/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,15 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Dashboard.Menu; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Dashboard.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddDashboardModule(this IServiceCollection services) + { + return services + .AddScoped() + .AddScoped(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Dashboard/Feature.cs b/src/modules/Elsa.Studio.Dashboard/Feature.cs new file mode 100644 index 0000000..3adcb13 --- /dev/null +++ b/src/modules/Elsa.Studio.Dashboard/Feature.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Abstractions; + +namespace Elsa.Studio.Dashboard; + +public class Feature : FeatureBase +{ + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Dashboard/FodyWeavers.xml b/src/modules/Elsa.Studio.Dashboard/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Dashboard/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Dashboard/FodyWeavers.xsd b/src/modules/Elsa.Studio.Dashboard/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Dashboard/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Dashboard/Menu/DashboardMenu.cs b/src/modules/Elsa.Studio.Dashboard/Menu/DashboardMenu.cs new file mode 100644 index 0000000..258cc98 --- /dev/null +++ b/src/modules/Elsa.Studio.Dashboard/Menu/DashboardMenu.cs @@ -0,0 +1,32 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Services; +using Microsoft.AspNetCore.Components.Routing; +using MudBlazor; + +namespace Elsa.Studio.Dashboard.Menu; + +/// +/// Provides the menu items for the Dashboard module. +/// +public class DashboardMenu(ILocalizer localizer) : IMenuProvider +{ + /// + public ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default) + { + var menuItems = new List + { + new() + { + Icon = Icons.Material.Outlined.SpaceDashboard, + Href = "", + Text = localizer["Dashboard"], + GroupName = MenuItemGroups.General.Name, + Match = NavLinkMatch.All + } + }; + + return new ValueTask>(menuItems); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Dashboard/Pages/Index.razor b/src/modules/Elsa.Studio.Dashboard/Pages/Index.razor new file mode 100644 index 0000000..027422e --- /dev/null +++ b/src/modules/Elsa.Studio.Dashboard/Pages/Index.razor @@ -0,0 +1,13 @@ +@page "/" +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +Index + + + + @Localizer["Manage all the things"] + @Localizer["You can find documentation and examples here"]: v3.elsaworkflows.io + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Dashboard/_Imports.razor b/src/modules/Elsa.Studio.Dashboard/_Imports.razor new file mode 100644 index 0000000..854cf75 --- /dev/null +++ b/src/modules/Elsa.Studio.Dashboard/_Imports.razor @@ -0,0 +1,6 @@ +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Elsa.Studio.Components +@using Elsa.Studio.Localization +@using MudBlazor +@attribute [Authorize] \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/Components/EnvironmentPicker.razor b/src/modules/Elsa.Studio.Environments/Components/EnvironmentPicker.razor new file mode 100644 index 0000000..f1f62eb --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Components/EnvironmentPicker.razor @@ -0,0 +1,49 @@ +@using MudBlazor +@using Elsa.Studio.Environments.Contracts +@using Elsa.Studio.Environments.Models +@inherits StudioComponentBase +@implements IDisposable +@inject IEnvironmentService EnvironmentService; + + + @foreach (var environment in EnvironmentService.Environments) + { + @environment.Name + } + + +@code +{ + private void ChangeEnvironment(ServerEnvironment environment) + { + EnvironmentService.SetCurrentEnvironment(environment.Name); + StateHasChanged(); + } + + protected override void OnInitialized() + { + EnvironmentService.EnvironmentsChanged += OnEnvironmentsChanged; + EnvironmentService.CurrentEnvironmentChanged += OnCurrentEnvironmentChanged; + } + + public void Dispose() + { + EnvironmentService.EnvironmentsChanged -= OnEnvironmentsChanged; + EnvironmentService.CurrentEnvironmentChanged -= OnCurrentEnvironmentChanged; + } + + private void OnEnvironmentsChanged() + { + StateHasChanged(); + } + + private void OnCurrentEnvironmentChanged() => StateHasChanged(); +} diff --git a/src/modules/Elsa.Studio.Environments/Contracts/IEnvironmentService.cs b/src/modules/Elsa.Studio.Environments/Contracts/IEnvironmentService.cs new file mode 100644 index 0000000..d6cdd5e --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Contracts/IEnvironmentService.cs @@ -0,0 +1,42 @@ +using Elsa.Studio.Environments.Models; + +namespace Elsa.Studio.Environments.Contracts; + +/// +/// Manages the environment in which the dashboard is running. +/// +public interface IEnvironmentService +{ + /// + /// Raised when the list of environments changed. + /// + event Action? EnvironmentsChanged; + + /// + /// Raised when the current environment changed. + /// + event Action CurrentEnvironmentChanged; + + /// + /// The current environment. + /// + ServerEnvironment? CurrentEnvironment { get; } + + /// + /// Gets or sets a list of environments. + /// + IEnumerable Environments { get; } + + /// + /// Sets the list of environments. + /// + /// The environments to set. + /// The name of the default environment. + void SetEnvironments(IEnumerable environments, string? defaultEnvironmentName = null); + + /// + /// Sets the current environment. + /// + /// The name of the current environment to set. + void SetCurrentEnvironment(string name); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/Contracts/IEnvironmentsClient.cs b/src/modules/Elsa.Studio.Environments/Contracts/IEnvironmentsClient.cs new file mode 100644 index 0000000..a668cb4 --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Contracts/IEnvironmentsClient.cs @@ -0,0 +1,20 @@ +using Elsa.Studio.Environments.Models; +using Refit; + +namespace Elsa.Studio.Environments.Contracts; + +/// +/// An HTTP client for the Environments API. +/// +public interface IEnvironmentsClient +{ + /// + /// Returns a list of environments from the API. + /// + /// The cancellation token. + /// A list of environments. + [Get("/environments")] + Task ListEnvironmentsAsync(CancellationToken cancellationToken = default); +} + +public record ListEnvironmentsResponse(ICollection Environments, string? DefaultEnvironmentName); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/Elsa.Studio.Environments.csproj b/src/modules/Elsa.Studio.Environments/Elsa.Studio.Environments.csproj new file mode 100644 index 0000000..f7860bc --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Elsa.Studio.Environments.csproj @@ -0,0 +1,22 @@ + + + + Adds support for connecting to different Elsa Workflows environments. + elsa studio module + + + + + + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Environments/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Environments/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..5fac01d --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Environments.Contracts; +using Elsa.Studio.Environments.Services; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Elsa.Studio.Environments.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the environments module. + /// + public static IServiceCollection AddEnvironmentsModule(this IServiceCollection services) + { + services.AddScoped(); + services.Replace(ServiceDescriptor.Scoped()); + //services.AddSingleton(); + services.AddScoped(); + return services; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/FodyWeavers.xml b/src/modules/Elsa.Studio.Environments/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/FodyWeavers.xsd b/src/modules/Elsa.Studio.Environments/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/Models/ServerEnvironment.cs b/src/modules/Elsa.Studio.Environments/Models/ServerEnvironment.cs new file mode 100644 index 0000000..aecc5b5 --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Models/ServerEnvironment.cs @@ -0,0 +1,22 @@ +namespace Elsa.Studio.Environments.Models; + +/// +/// Represents the environment in which the workflow engine is running. +/// +public class ServerEnvironment +{ + /// + /// The name of the environment. + /// + public string Name { get; set; } = default!; + + /// + /// The URL of the server hosting the workflow engine. + /// + public Uri Url { get; set; } = default!; + + /// + /// A dictionary of custom properties. + /// + public IDictionary CustomProperties { get; set; } = new Dictionary(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/Module.cs b/src/modules/Elsa.Studio.Environments/Module.cs new file mode 100644 index 0000000..43094fe --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Module.cs @@ -0,0 +1,15 @@ +using Elsa.Studio.Abstractions; +using Elsa.Studio.Contracts; +using Elsa.Studio.Environments.Components; + +namespace Elsa.Studio.Environments; + +public class Feature(IAppBarService appBarService) : FeatureBase +{ + public override ValueTask InitializeAsync(CancellationToken cancellationToken = default) + { + appBarService.AddAppBarItem(); + + return ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/Services/DefaultEnvironmentService.cs b/src/modules/Elsa.Studio.Environments/Services/DefaultEnvironmentService.cs new file mode 100644 index 0000000..5b2ce2a --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Services/DefaultEnvironmentService.cs @@ -0,0 +1,38 @@ +using Elsa.Studio.Environments.Contracts; +using Elsa.Studio.Environments.Models; + +namespace Elsa.Studio.Environments.Services; + +public class DefaultEnvironmentService : IEnvironmentService +{ + public event Action? EnvironmentsChanged; + public event Action? CurrentEnvironmentChanged; + + public ServerEnvironment? CurrentEnvironment { get; private set; } + public IEnumerable Environments { get; private set; } = new List(); + + public void SetEnvironments(IEnumerable environments, string? defaultEnvironmentName = null) + { + var environmentList = environments.ToList(); + Environments = environmentList; + + if (defaultEnvironmentName != null) + SetCurrentEnvironment(defaultEnvironmentName); + else if (CurrentEnvironment == null) + SetCurrentEnvironment(environmentList.FirstOrDefault()?.Name ?? string.Empty); + + EnvironmentsChanged?.Invoke(); + } + + public void SetCurrentEnvironment(string name) + { + var environments = Environments.ToList(); + var environment = environments.FirstOrDefault(x => x.Name == name); + + if (environment == null || CurrentEnvironment == environment) + return; + + CurrentEnvironment = environment; + CurrentEnvironmentChanged?.Invoke(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/Services/EnvironmentBackendApiClientProvider.cs b/src/modules/Elsa.Studio.Environments/Services/EnvironmentBackendApiClientProvider.cs new file mode 100644 index 0000000..7986eec --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Services/EnvironmentBackendApiClientProvider.cs @@ -0,0 +1,38 @@ +using Elsa.Api.Client.Extensions; +using Elsa.Studio.Contracts; +using Elsa.Studio.Environments.Contracts; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Environments.Services; + +/// +/// An environment-aware backend connection provider that returns the URL to the currently selected environment, if any. +/// +public class EnvironmentBackendApiClientProvider : IBackendApiClientProvider +{ + private readonly IEnvironmentService _environmentService; + private readonly IRemoteBackendAccessor _remoteBackendAccessor; + + /// + /// Initializes a new instance of the class. + /// + public EnvironmentBackendApiClientProvider(IEnvironmentService environmentService, IRemoteBackendAccessor remoteBackendAccessor) + { + _environmentService = environmentService; + _remoteBackendAccessor = remoteBackendAccessor; + } + + /// + public Uri Url => _environmentService.CurrentEnvironment?.Url ?? _remoteBackendAccessor.RemoteBackend.Url; + + /// + public async ValueTask GetApiAsync(CancellationToken cancellationToken = default) where T : class + { + var services = new ServiceCollection().AddDefaultApiClients(x => + { + x.BaseAddress = Url; + //x.ConfigureHttpClient = httpClient => httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + }).BuildServiceProvider(); + return services.GetRequiredService(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/Tasks/LoadEnvironmentsStartupTask.cs b/src/modules/Elsa.Studio.Environments/Tasks/LoadEnvironmentsStartupTask.cs new file mode 100644 index 0000000..31a6472 --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/Tasks/LoadEnvironmentsStartupTask.cs @@ -0,0 +1,13 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Environments.Contracts; + +namespace Elsa.Studio.Environments.Tasks; + +public class LoadEnvironmentsStartupTask(IEnvironmentsClient environmentsClient, IEnvironmentService environmentService) : IStartupTask +{ + public async ValueTask ExecuteAsync(CancellationToken cancellationToken = default) + { + var response = await environmentsClient.ListEnvironmentsAsync(cancellationToken); + environmentService.SetEnvironments(response.Environments, response.DefaultEnvironmentName); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Environments/_Imports.razor b/src/modules/Elsa.Studio.Environments/_Imports.razor new file mode 100644 index 0000000..33be4d4 --- /dev/null +++ b/src/modules/Elsa.Studio.Environments/_Imports.razor @@ -0,0 +1,4 @@ +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Elsa.Studio.Components +@attribute [Authorize] \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization.BlazorServer/Controllers/CultureController.cs b/src/modules/Elsa.Studio.Localization.BlazorServer/Controllers/CultureController.cs new file mode 100644 index 0000000..ea331d8 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorServer/Controllers/CultureController.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Mvc; + +namespace Elsa.Studio.Localization.BlazorServer.Controllers; + +/// +/// Controller for setting the culture. +/// +[Route("[controller]/[action]")] +public class CultureController : Controller +{ + /// + /// Sets the culture and redirects to the specified URI. + /// + public IActionResult Set(string? culture, string redirectUri) + { + if (culture != null) + { + HttpContext.Response.Cookies.Append( + CookieRequestCultureProvider.DefaultCookieName, + CookieRequestCultureProvider.MakeCookieValue( + new RequestCulture(culture, culture))); + } + + return LocalRedirect(redirectUri); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization.BlazorServer/Elsa.Studio.Localization.BlazorServer.csproj b/src/modules/Elsa.Studio.Localization.BlazorServer/Elsa.Studio.Localization.BlazorServer.csproj new file mode 100644 index 0000000..dfe9ba1 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorServer/Elsa.Studio.Localization.BlazorServer.csproj @@ -0,0 +1,15 @@ + + + + Adds support for localization to Elsa Studio Blazor Server Apps. + elsa studio module + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Localization.BlazorServer/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Localization.BlazorServer/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..8aed2dc --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorServer/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +using Elsa.Studio.Localization.BlazorServer.Services; +using Elsa.Studio.Localization.Extensions; +using Elsa.Studio.Localization.Models; +using Elsa.Studio.Localization.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Localization.BlazorServer.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddLocalizationModule(this IServiceCollection services, LocalizationConfig localizationConfig) + { + services.AddControllers(); + services.AddLocalizationModuleCore(localizationConfig); + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization.BlazorServer/Extensions/WebApplicationExtensions.cs b/src/modules/Elsa.Studio.Localization.BlazorServer/Extensions/WebApplicationExtensions.cs new file mode 100644 index 0000000..7664991 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorServer/Extensions/WebApplicationExtensions.cs @@ -0,0 +1,28 @@ +using Elsa.Studio.Localization.Options; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace Elsa.Studio.Localization.BlazorServer.Extensions; + +public static class WebApplicationExtensions +{ + public static WebApplication UseElsaLocalization(this WebApplication app) + { + var localisationOptions = app.Services.GetService>()?.Value; + var defaultCulture = localisationOptions?.DefaultCulture; + var supportedCultures = localisationOptions?.SupportedCultures; + + if (supportedCultures != null) + { + var localizationOptions = new RequestLocalizationOptions() + .SetDefaultCulture(defaultCulture ?? new LocalizationOptions().DefaultCulture) + .AddSupportedCultures(supportedCultures) + .AddSupportedUICultures(supportedCultures); + + app.UseRequestLocalization(localizationOptions); + } + + return app; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization.BlazorServer/Services/BlazorServerCultureService.cs b/src/modules/Elsa.Studio.Localization.BlazorServer/Services/BlazorServerCultureService.cs new file mode 100644 index 0000000..4bc5a0e --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorServer/Services/BlazorServerCultureService.cs @@ -0,0 +1,31 @@ +using Elsa.Studio.Localization.Services; +using Microsoft.AspNetCore.Components; +using System.Globalization; + +namespace Elsa.Studio.Localization.BlazorServer.Services; + +/// +public class BlazorServerCultureService(NavigationManager navigationManager) : ICultureService +{ + /// + public Task ChangeCultureAsync(CultureInfo culture) + { + if (CultureInfo.CurrentUICulture.Name != culture.Name) + { + var cultureString = culture.Name; + var uri = new Uri(navigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped); + + // Set culture of the current thread. + CultureInfo.CurrentCulture = culture; + CultureInfo.CurrentUICulture = culture; + var cultureEscaped = Uri.EscapeDataString(cultureString); + var uriEscaped = Uri.EscapeDataString(uri); + + navigationManager.NavigateTo( + $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}", + forceLoad: true); + } + + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization.BlazorWasm/Elsa.Studio.Localization.BlazorWasm.csproj b/src/modules/Elsa.Studio.Localization.BlazorWasm/Elsa.Studio.Localization.BlazorWasm.csproj new file mode 100644 index 0000000..14ccf19 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorWasm/Elsa.Studio.Localization.BlazorWasm.csproj @@ -0,0 +1,19 @@ + + + + Adds support for localization to Elsa Studio Blazor Wasm Apps. + elsa studio module + + + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Localization.BlazorWasm/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Localization.BlazorWasm/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..0208530 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorWasm/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,20 @@ +using Elsa.Studio.Localization.BlazorWasm.Services; +using Elsa.Studio.Localization.Extensions; +using Elsa.Studio.Localization.Models; +using Elsa.Studio.Localization.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Localization.BlazorWasm.Extensions +{ + public static class ServiceCollectionExtensions + { + public static IServiceCollection AddLocalizationModule(this IServiceCollection services, LocalizationConfig localizationConfig) + { + services.AddLocalizationModuleCore(localizationConfig); + + services.AddScoped(); + + return services; + } + } +} diff --git a/src/modules/Elsa.Studio.Localization.BlazorWasm/Extensions/WebAssemblyHostExtensions.cs b/src/modules/Elsa.Studio.Localization.BlazorWasm/Extensions/WebAssemblyHostExtensions.cs new file mode 100644 index 0000000..bc66681 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorWasm/Extensions/WebAssemblyHostExtensions.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Elsa.Studio.Localization.BlazorWasm.Extensions +{ + public static class WebAssemblyHostExtensions + { + public static async Task UseElsaLocalization(this WebAssemblyHost host) { + + const string defaultCulture = "en-US"; + var js = host.Services.GetRequiredService(); + var module = await js.InvokeAsync("import", "./_content/Elsa.Studio.Localization.BlazorWasm/blazorCulture.js"); + var result = await js.InvokeAsync("blazorCulture.get"); + + var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture); + + if (result == null) + { + await js.InvokeVoidAsync("blazorCulture.set", defaultCulture); + } + + CultureInfo.DefaultThreadCurrentCulture = culture; + CultureInfo.DefaultThreadCurrentUICulture = culture; + + return host; + } + } +} diff --git a/src/modules/Elsa.Studio.Localization.BlazorWasm/Services/BlazorWasmCultureService.cs b/src/modules/Elsa.Studio.Localization.BlazorWasm/Services/BlazorWasmCultureService.cs new file mode 100644 index 0000000..7a24a1d --- /dev/null +++ b/src/modules/Elsa.Studio.Localization.BlazorWasm/Services/BlazorWasmCultureService.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Localization.Services; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using System.Globalization; + +namespace Elsa.Studio.Localization.BlazorWasm.Services +{ + /// + public class BlazorWasmCultureService(NavigationManager navigationManager, IJSRuntime jSRuntime) : ICultureService + { + private IJSObjectReference? _module; + + /// + public async Task ChangeCultureAsync(CultureInfo culture) + { + if (CultureInfo.CurrentUICulture.Name != culture.Name) + { + _module = await jSRuntime.InvokeAsync("import", "./_content/Elsa.Studio.Localization.BlazorWasm/blazorCulture.js"); + await jSRuntime.InvokeVoidAsync("blazorCulture.set", culture.Name); + + navigationManager.NavigateTo(navigationManager.Uri, forceLoad: true); + } + } + } +} diff --git a/src/modules/Elsa.Studio.Localization/Components/LanguagePicker.razor b/src/modules/Elsa.Studio.Localization/Components/LanguagePicker.razor new file mode 100644 index 0000000..ae92bb8 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/Components/LanguagePicker.razor @@ -0,0 +1,32 @@ +@inject IOptions LocalizationOptions +@inject ICultureService CultureService + + + @foreach (var culture in _cultures) + { + @LocalizationOptions.Value.CulturePickerFormatter(culture) + } + + +@code { + private List _cultures = []; + + /// + protected override void OnInitialized() + { + _cultures = LocalizationOptions.Value?.SupportedCultures.Select(s => new CultureInfo(s)).ToList() ?? []; + } + + private async void ChangeCulture(CultureInfo culture) + { + await CultureService.ChangeCultureAsync(culture); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization/Elsa.Studio.Localization.csproj b/src/modules/Elsa.Studio.Localization/Elsa.Studio.Localization.csproj new file mode 100644 index 0000000..e228dc3 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/Elsa.Studio.Localization.csproj @@ -0,0 +1,21 @@ + + + + Adds support for localization to Elsa Studio. + elsa studio module + + + + + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Localization/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Localization/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..5780224 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,19 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization.Models; +using Microsoft.Extensions.DependencyInjection; +using MudBlazor.Translations; + +namespace Elsa.Studio.Localization.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddLocalizationModuleCore(this IServiceCollection services,LocalizationConfig localizationConfig) + { + services.AddLocalization(); + services.AddMudTranslations(); + services.Configure(localizationConfig.ConfigureLocalizationOptions); + services.AddScoped(); + + return services; + } +} diff --git a/src/modules/Elsa.Studio.Localization/FodyWeavers.xml b/src/modules/Elsa.Studio.Localization/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization/FodyWeavers.xsd b/src/modules/Elsa.Studio.Localization/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization/LocalizationFeature.cs b/src/modules/Elsa.Studio.Localization/LocalizationFeature.cs new file mode 100644 index 0000000..07bd6e0 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/LocalizationFeature.cs @@ -0,0 +1,14 @@ +using Elsa.Studio.Abstractions; +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization.Components; + +namespace Elsa.Studio.Localization; +public class LocalizationFeature(IAppBarService appBarService) : FeatureBase +{ + public override ValueTask InitializeAsync(CancellationToken cancellationToken = default) + { + appBarService.AddAppBarItem(); + + return ValueTask.CompletedTask; + } +} diff --git a/src/modules/Elsa.Studio.Localization/Models/LocalizationConfig.cs b/src/modules/Elsa.Studio.Localization/Models/LocalizationConfig.cs new file mode 100644 index 0000000..5b84158 --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/Models/LocalizationConfig.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Localization.Options; + +namespace Elsa.Studio.Localization.Models; + +public class LocalizationConfig +{ + public Action ConfigureLocalizationOptions { get; set; } = _ => { }; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization/Options/LocalizationOptions.cs b/src/modules/Elsa.Studio.Localization/Options/LocalizationOptions.cs new file mode 100644 index 0000000..6c4801b --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/Options/LocalizationOptions.cs @@ -0,0 +1,26 @@ +using System.Globalization; + +namespace Elsa.Studio.Localization.Options; + +/// +/// Options for localization settings. +/// +public class LocalizationOptions +{ + public static string LocalizationSection = "Localization"; + + /// + /// Gets or sets the supported cultures. + /// + public string[] SupportedCultures { get; set; } = []; + + /// + /// Gets or sets the default culture. + /// + public string DefaultCulture { get; set; } = "en-US"; + + /// + /// Gets or sets the culture picker formatter + /// + public Func CulturePickerFormatter { get; set; } = info => info.Name; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization/README.md b/src/modules/Elsa.Studio.Localization/README.md new file mode 100644 index 0000000..9db203a --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/README.md @@ -0,0 +1,71 @@ +# Elsa Studio Localization +Elsa Studio Localization Allows localizing the Studio UI to different languages. + +`ILocalizationProvider` is the interface that needs to be implemented to provide the localized strings for the Studio UI. + +Create your own localization file (Using the resource file or any alternative method' and implement the `ILocalizationProvider` interface. + +Afterwards, register your implementation in the DI container. + +```cssharp +builder.Services.AddSingleton(); +``` + +## Steps to Enable Localization + +### For Blazor Server +1. Add Reference to `Elsa.Studio.Localization.BlazorServer` package. +1. Define the Localization Configuration + ```csharp + var localizationConfig = new LocalizationConfig + { + ConfigureLocalizationOptions = options => configuration.GetSection("Localization").Bind(options), + }; + ``` +1. Register the Localization Module `builder.Services.AddLocalizationModule();` +1. Register your locallization provider + ```csharp + builder.Services.AddSingleton(); + ``` +1. Add The localization Middleware. Making Sure that Controllers are also mapped. + ```csharp + app.UseElsaLocalization(); + app.MapControllers(); + ``` +1. Add below configuration in the `appsettings.json` file, specifying the supported cultures. + ```json + "Localization": { + "SupportedCultures": [ + "ja-JP", + "fr-FR" + ] + } + ``` + +### For Blazor WebAssembly +1. Add Reference to `Elsa.Studio.Localization.BlazorWasm` package. +1. Define the Localization Configuration + ```csharp + var localizationConfig = new LocalizationConfig + { + ConfigureLocalizationOptions = options => configuration.GetSection("Localization").Bind(options), + }; + ``` +1. Register the Localization Module `builder.Services.AddLocalizationModule();` +1. Register your locallization provider + ```csharp + builder.Services.AddSingleton(); + ``` +1. Use the localization Middleware + ```csharp + await app.UseElsaLocalization(); + ``` +1. Add below configuration in the `appsettings.json` file, specifying the supported cultures. + ```json + "Localization": { + "SupportedCultures": [ + "ja-JP", + "fr-FR" + ] + } + ``` \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization/Services/ICultureService.cs b/src/modules/Elsa.Studio.Localization/Services/ICultureService.cs new file mode 100644 index 0000000..4be127c --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/Services/ICultureService.cs @@ -0,0 +1,14 @@ +using System.Globalization; + +namespace Elsa.Studio.Localization.Services; + +/// +/// Service to change the culture of the application. +/// +public interface ICultureService +{ + /// + /// Change the culture of the application. + /// + Task ChangeCultureAsync(CultureInfo culture); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Localization/_Imports.razor b/src/modules/Elsa.Studio.Localization/_Imports.razor new file mode 100644 index 0000000..d3a381c --- /dev/null +++ b/src/modules/Elsa.Studio.Localization/_Imports.razor @@ -0,0 +1,9 @@ +@using Elsa.Studio.Components +@using Elsa.Studio.Localization.Options +@using Elsa.Studio.Localization.Services +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.Extensions.Options +@using Microsoft.JSInterop +@using MudBlazor +@using System.Globalization \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorServer/Elsa.Studio.Login.BlazorServer.csproj b/src/modules/Elsa.Studio.Login.BlazorServer/Elsa.Studio.Login.BlazorServer.csproj new file mode 100644 index 0000000..3a4a707 --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorServer/Elsa.Studio.Login.BlazorServer.csproj @@ -0,0 +1,17 @@ + + + + Elsa Studio Login module for Blazor Server apps. + elsa studio module login blazor server + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Login.BlazorServer/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Login.BlazorServer/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..de90e61 --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorServer/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,34 @@ +using Blazored.LocalStorage; +using Elsa.Studio.Login.BlazorServer.Services; +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Extensions; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Login.BlazorServer.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds login services with Blazor Server implementations. + /// + public static IServiceCollection AddLoginModule(this IServiceCollection services) + { + // Add the login module. + services.AddLoginModuleCore(); + + // Register HttpContextAccessor. + services.AddHttpContextAccessor(); + + // Register Blazored LocalStorage. + services.AddBlazoredLocalStorage(); + + // Register JWT services. + services.AddSingleton(); + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorServer/FodyWeavers.xml b/src/modules/Elsa.Studio.Login.BlazorServer/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorServer/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorServer/FodyWeavers.xsd b/src/modules/Elsa.Studio.Login.BlazorServer/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorServer/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorServer/Services/BlazorServerJwtAccessor.cs b/src/modules/Elsa.Studio.Login.BlazorServer/Services/BlazorServerJwtAccessor.cs new file mode 100644 index 0000000..8fa7bef --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorServer/Services/BlazorServerJwtAccessor.cs @@ -0,0 +1,40 @@ +using Blazored.LocalStorage; +using Elsa.Studio.Login.Contracts; +using Microsoft.AspNetCore.Http; + +namespace Elsa.Studio.Login.BlazorServer.Services; + +/// +/// Implements the interface for server-side Blazor. +/// +public class BlazorServerJwtAccessor : IJwtAccessor +{ + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly ILocalStorageService _localStorageService; + + /// + /// Initializes a new instance of the class. + /// + public BlazorServerJwtAccessor(IHttpContextAccessor httpContextAccessor, ILocalStorageService localStorageService) + { + _httpContextAccessor = httpContextAccessor; + _localStorageService = localStorageService; + } + + /// + public async ValueTask ReadTokenAsync(string name) + { + if (IsPrerendering()) + return null; + + return await _localStorageService.GetItemAsync(name); + } + + /// + public async ValueTask WriteTokenAsync(string name, string token) + { + await _localStorageService.SetItemAsStringAsync(name, token); + } + + private bool IsPrerendering() => _httpContextAccessor.HttpContext?.Response.HasStarted == false; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorServer/Services/BlazorServerJwtParser.cs b/src/modules/Elsa.Studio.Login.BlazorServer/Services/BlazorServerJwtParser.cs new file mode 100644 index 0000000..32162e0 --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorServer/Services/BlazorServerJwtParser.cs @@ -0,0 +1,17 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using Elsa.Studio.Login.Contracts; + +namespace Elsa.Studio.Login.BlazorServer.Services; + +/// +public class BlazorServerJwtParser : IJwtParser +{ + /// + public IEnumerable Parse(string jwt) + { + var handler = new JwtSecurityTokenHandler(); + var jwtSecurityToken = handler.ReadJwtToken(jwt); + return jwtSecurityToken.Claims; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorWasm/Elsa.Studio.Login.BlazorWasm.csproj b/src/modules/Elsa.Studio.Login.BlazorWasm/Elsa.Studio.Login.BlazorWasm.csproj new file mode 100644 index 0000000..b0d890e --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorWasm/Elsa.Studio.Login.BlazorWasm.csproj @@ -0,0 +1,12 @@ + + + + Elsa Studio Login module for Blazor Web Assembly apps. + elsa studio module login blazor wasm + + + + + + + diff --git a/src/modules/Elsa.Studio.Login.BlazorWasm/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Login.BlazorWasm/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..a080cb9 --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorWasm/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,31 @@ +using Blazored.LocalStorage; +using Elsa.Studio.Login.BlazorWasm.Services; +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Extensions; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Login.BlazorWasm.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds login services with Blazor Server implementations. + /// + public static IServiceCollection AddLoginModule(this IServiceCollection services) + { + // Add the login module. + services.AddLoginModuleCore(); + + // Register Blazored LocalStorage. + services.AddBlazoredLocalStorage(); + + // Register JWT services. + services.AddSingleton(); + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorWasm/FodyWeavers.xml b/src/modules/Elsa.Studio.Login.BlazorWasm/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorWasm/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorWasm/FodyWeavers.xsd b/src/modules/Elsa.Studio.Login.BlazorWasm/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorWasm/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorWasm/Services/BlazorWasmJwtAccessor.cs b/src/modules/Elsa.Studio.Login.BlazorWasm/Services/BlazorWasmJwtAccessor.cs new file mode 100644 index 0000000..f63855e --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorWasm/Services/BlazorWasmJwtAccessor.cs @@ -0,0 +1,31 @@ +using Blazored.LocalStorage; +using Elsa.Studio.Login.Contracts; + +namespace Elsa.Studio.Login.BlazorWasm.Services; + +/// +public class BlazorWasmJwtAccessor : IJwtAccessor +{ + private readonly ILocalStorageService _localStorageService; + + /// + /// + /// + /// + public BlazorWasmJwtAccessor(ILocalStorageService localStorageService) + { + _localStorageService = localStorageService; + } + + /// + public async ValueTask ReadTokenAsync(string name) + { + return await _localStorageService.GetItemAsync(name); + } + + /// + public async ValueTask WriteTokenAsync(string name, string token) + { + await _localStorageService.SetItemAsStringAsync(name, token); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login.BlazorWasm/Services/BlazorWasmJwtParser.cs b/src/modules/Elsa.Studio.Login.BlazorWasm/Services/BlazorWasmJwtParser.cs new file mode 100644 index 0000000..d7589f1 --- /dev/null +++ b/src/modules/Elsa.Studio.Login.BlazorWasm/Services/BlazorWasmJwtParser.cs @@ -0,0 +1,43 @@ +using Elsa.Studio.Login.Contracts; +using Microsoft.AspNetCore.WebUtilities; +using System.Security.Claims; +using System.Text.Json; +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Login.BlazorWasm.Services; + +/// +public class BlazorWasmJwtParser : IJwtParser +{ + // Taken and adapted from: https://trystanwilcock.com/2022/09/28/net-6-0-blazor-webassembly-jwt-token-authentication-from-scratch-c-sharp-wasm-tutorial/ + /// + public IEnumerable Parse(string jwt) + { + var payload = jwt.Split('.')[1]; + var jsonBytes = WebEncoders.Base64UrlDecode(payload); + var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes)!; + foreach (var (key, value) in keyValuePairs) + { + // Having an ClaimsIdentity with the following claims + // new Claim("A", "val1"); + // new Claim("A", "val2"); + // is serialized as + // { "A": ["val1", "val2"] } + // so handle that here + if (value is JsonArray array) + { + foreach (var arrayValue in array) + { + if (arrayValue != null) + { + yield return new Claim(key, arrayValue.ToString()); + } + } + } + else + { + yield return new Claim(key, value.ToString()); + } + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/ComponentProviders/RedirectToLoginUnauthorizedComponentProvider.cs b/src/modules/Elsa.Studio.Login/ComponentProviders/RedirectToLoginUnauthorizedComponentProvider.cs new file mode 100644 index 0000000..40608d0 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/ComponentProviders/RedirectToLoginUnauthorizedComponentProvider.cs @@ -0,0 +1,16 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Login.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Login.ComponentProviders; + +/// +public class RedirectToLoginUnauthorizedComponentProvider : IUnauthorizedComponentProvider +{ + /// + public RenderFragment GetUnauthorizedComponent() + { + return builder => builder.CreateComponent(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Components/LoginState.razor b/src/modules/Elsa.Studio.Login/Components/LoginState.razor new file mode 100644 index 0000000..2a673d8 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Components/LoginState.razor @@ -0,0 +1,42 @@ +@using Elsa.Studio.Login.Contracts +@using Microsoft.AspNetCore.Components.Authorization +@inherits StudioComponentBase +@implements IDisposable +@inject AuthenticationStateProvider AuthenticationStateProvider +@inject IEndSessionService EndSessionService + +@if (@CurrentState?.User.Identity?.IsAuthenticated is true) +{ + + Logout + +} + +@code +{ + private AuthenticationState? CurrentState; + + protected override async Task OnInitializedAsync() + { + CurrentState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); + AuthenticationStateProvider.AuthenticationStateChanged += OnCurrentEnvironmentChanged; + } + + public void Dispose() + { + AuthenticationStateProvider.AuthenticationStateChanged -= OnCurrentEnvironmentChanged; + } + + private async void OnCurrentEnvironmentChanged(Task state) + { + CurrentState = await state; + StateHasChanged(); + } +} diff --git a/src/modules/Elsa.Studio.Login/Components/ReceiveAuthorizationCode.cs b/src/modules/Elsa.Studio.Login/Components/ReceiveAuthorizationCode.cs new file mode 100644 index 0000000..4bc64c5 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Components/ReceiveAuthorizationCode.cs @@ -0,0 +1,30 @@ +using Elsa.Studio.Components; +using Elsa.Studio.Login.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Login.Components; + +/// +/// Receives the OIDC authorization code and trades it for access_token +/// +[Route("/signin-oidc")] +public sealed class ReceiveAuthorizationCode : StudioComponentBase +{ + /// + /// Gets or sets the . + /// + [Inject] private IAuthorizationService AuthorizationService { get; set; } = default!; + + [SupplyParameterFromQuery(Name = "code")] private string? AuthorizationCode { get; set; } + + [SupplyParameterFromQuery(Name = "state")] private string? State { get; set; } + + /// + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (AuthorizationCode != null) + { + await AuthorizationService.ReceiveAuthorizationCode(AuthorizationCode, State, default); + } + } +} diff --git a/src/modules/Elsa.Studio.Login/Components/RedirectToLogin.cs b/src/modules/Elsa.Studio.Login/Components/RedirectToLogin.cs new file mode 100644 index 0000000..2722818 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Components/RedirectToLogin.cs @@ -0,0 +1,21 @@ +using Elsa.Studio.Login.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Login.Components; + +/// +/// Redirects to the login page. +/// +public class RedirectToLogin : ComponentBase +{ + /// + /// Gets or sets the . + /// + [Inject] protected IAuthorizationService AuthorizationService { get; set; } = default!; + + /// + protected override Task OnAfterRenderAsync(bool firstRender) + { + return AuthorizationService.RedirectToAuthorizationServer(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Contracts/IAuthorizationService.cs b/src/modules/Elsa.Studio.Login/Contracts/IAuthorizationService.cs new file mode 100644 index 0000000..aa06458 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Contracts/IAuthorizationService.cs @@ -0,0 +1,17 @@ +namespace Elsa.Studio.Login.Contracts; + +/// +/// Provides a service to acquire an access_token from an authorization server +/// +public interface IAuthorizationService +{ + /// + /// Redirects the user agent to the authorization server for authentication + /// + Task RedirectToAuthorizationServer(); + + /// + /// Trades a authorization code received from the authorization server for an access_token + /// + Task ReceiveAuthorizationCode(string code, string? state, CancellationToken cancellationToken); +} diff --git a/src/modules/Elsa.Studio.Login/Contracts/ICredentialsValidator.cs b/src/modules/Elsa.Studio.Login/Contracts/ICredentialsValidator.cs new file mode 100644 index 0000000..ed7b220 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Contracts/ICredentialsValidator.cs @@ -0,0 +1,18 @@ +using Elsa.Studio.Login.Models; + +namespace Elsa.Studio.Login.Contracts; + +/// +/// A validator for credentials. +/// +public interface ICredentialsValidator +{ + /// + /// Validates the credentials. + /// + /// The username. + /// The password. + /// An optional cancellation token. + /// A instance. + ValueTask ValidateCredentialsAsync(string username, string password, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Contracts/IEndSessionService.cs b/src/modules/Elsa.Studio.Login/Contracts/IEndSessionService.cs new file mode 100644 index 0000000..7d72aed --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Contracts/IEndSessionService.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Login.Contracts; + +/// +/// Provides a service to end the session with an authorization server +/// +public interface IEndSessionService +{ + /// + /// Remove authentication state and end the session with the authorization server + /// + Task LogoutAsync(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Contracts/IJwtAccessor.cs b/src/modules/Elsa.Studio.Login/Contracts/IJwtAccessor.cs new file mode 100644 index 0000000..388d43a --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Contracts/IJwtAccessor.cs @@ -0,0 +1,17 @@ +namespace Elsa.Studio.Login.Contracts; + +/// +/// Reads the token from storage (e.g. cookie, local storage, etc.). +/// +public interface IJwtAccessor +{ + /// + /// Reads the token from storage (e.g. cookie, local storage, etc.). + /// + ValueTask ReadTokenAsync(string name); + + /// + /// Writes the token to storage (e.g. cookie, local storage, etc.). + /// + ValueTask WriteTokenAsync(string name, string token); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Contracts/IJwtParser.cs b/src/modules/Elsa.Studio.Login/Contracts/IJwtParser.cs new file mode 100644 index 0000000..752894f --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Contracts/IJwtParser.cs @@ -0,0 +1,14 @@ +using System.Security.Claims; + +namespace Elsa.Studio.Login.Contracts; + +/// +/// Parses a JWT token and returns the claims. +/// +public interface IJwtParser +{ + /// + /// Parses a JWT token and returns the claims. + /// + IEnumerable Parse(string jwt); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Contracts/IRefreshTokenService.cs b/src/modules/Elsa.Studio.Login/Contracts/IRefreshTokenService.cs new file mode 100644 index 0000000..8b44d0c --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Contracts/IRefreshTokenService.cs @@ -0,0 +1,14 @@ +using Elsa.Api.Client.Resources.Identity.Responses; + +namespace Elsa.Studio.Login.Contracts; + +/// +/// Provides a service to refresh an access_token from an authorization server +/// +public interface IRefreshTokenService +{ + /// + /// Refreshes the access_token + /// + Task RefreshTokenAsync(CancellationToken cancellationToken); +} diff --git a/src/modules/Elsa.Studio.Login/Elsa.Studio.Login.csproj b/src/modules/Elsa.Studio.Login/Elsa.Studio.Login.csproj new file mode 100644 index 0000000..a21f422 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Elsa.Studio.Login.csproj @@ -0,0 +1,26 @@ + + + + Adds a user login screen that integrates with the `Elsa.Identity` backend module. + elsa studio module + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Login/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Login/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..8fd7fe5 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,80 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Login.ComponentProviders; +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.HttpMessageHandlers; +using Elsa.Studio.Login.Models; +using Elsa.Studio.Login.Services; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace Elsa.Studio.Login.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the login module to the service collection. + /// + public static IServiceCollection AddLoginModuleCore(this IServiceCollection services) + { + return services + .AddScoped() + .AddOptions() + .AddAuthorizationCore() + .AddScoped() + .AddScoped() + .AddScoped() + ; + } + + /// + /// Configures the login module to use elsa identity + /// + public static IServiceCollection UseElsaIdentity(this IServiceCollection services) + { + return services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + ; + } + + /// + /// Configures the service collection to use OAuth2 for credential validation and related services. + /// + public static IServiceCollection UseOAuth2(this IServiceCollection services, Action configure) + { + services.Configure(configure); + + services.AddHttpClient(httpClient => + { + var options = services.BuildServiceProvider().GetRequiredService>().Value; + httpClient.BaseAddress = new(options.TokenEndpoint); + }); + + return services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + ; + } + + /// + /// Configures the login module to use OpenIdConnect (OIDC) + /// + public static IServiceCollection UseOpenIdConnect(this IServiceCollection services, Action configure) + { + services.Configure(configure); + + return services + .AddScoped() + .AddScoped() + .AddScoped() + ; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/FodyWeavers.xml b/src/modules/Elsa.Studio.Login/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Login/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/FodyWeavers.xsd b/src/modules/Elsa.Studio.Login/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Login/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/HttpMessageHandlers/AuthenticatingApiHttpMessageHandler.cs b/src/modules/Elsa.Studio.Login/HttpMessageHandlers/AuthenticatingApiHttpMessageHandler.cs new file mode 100644 index 0000000..5e39eaa --- /dev/null +++ b/src/modules/Elsa.Studio.Login/HttpMessageHandlers/AuthenticatingApiHttpMessageHandler.cs @@ -0,0 +1,36 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Login.Contracts; +using Microsoft.Extensions.DependencyInjection; +using System.Net; + +namespace Elsa.Studio.Login.HttpMessageHandlers; + +/// +/// An that configures the outgoing HTTP request to use the access token as bearer token. +/// +public class AuthenticatingApiHttpMessageHandler(IRefreshTokenService refreshTokenService, IBlazorServiceAccessor blazorServiceAccessor) + : DelegatingHandler +{ + /// + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var sp = blazorServiceAccessor.Services; + var jwtAccessor = sp.GetRequiredService(); + var accessToken = await jwtAccessor.ReadTokenAsync(TokenNames.AccessToken); + request.Headers.Authorization = new("Bearer", accessToken); + + var response = await base.SendAsync(request, cancellationToken); + + if (response.StatusCode == HttpStatusCode.Unauthorized) + { + // Refresh token and retry once. + var tokens = await refreshTokenService.RefreshTokenAsync(cancellationToken); + request.Headers.Authorization = new("Bearer", tokens.AccessToken); + + // Retry. + response = await base.SendAsync(request, cancellationToken); + } + + return response; + } +} diff --git a/src/modules/Elsa.Studio.Login/LoginFeature.cs b/src/modules/Elsa.Studio.Login/LoginFeature.cs new file mode 100644 index 0000000..4b30fd8 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/LoginFeature.cs @@ -0,0 +1,16 @@ +using Elsa.Studio.Abstractions; +using Elsa.Studio.Contracts; +using Elsa.Studio.Login.Components; + +namespace Elsa.Studio.Login; + +/// +public class LoginFeature(IAppBarService appBarService) : FeatureBase +{ + /// + public override ValueTask InitializeAsync(CancellationToken cancellationToken = default) + { + appBarService.AddAppBarItem(); + return base.InitializeAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Models/IdentityTokenOptions.cs b/src/modules/Elsa.Studio.Login/Models/IdentityTokenOptions.cs new file mode 100644 index 0000000..cf23026 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Models/IdentityTokenOptions.cs @@ -0,0 +1,20 @@ +using Elsa.Studio.Login.Services; +using System.Security.Claims; + +namespace Elsa.Studio.Login.Models; + +/// +/// Provides options to configure how a ClaimsIdentity is created by +/// +public class IdentityTokenOptions +{ + /// + /// The claim type that is being used to identify the name of the created ClaimsIdentity + /// + public string NameClaimType { get; set; } = ClaimsIdentity.DefaultNameClaimType; + + /// + /// The claim type that is being used to identify the role of the created ClaimsIdentity + /// + public string RoleClaimType { get; set; } = ClaimsIdentity.DefaultRoleClaimType; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Models/OAuth2CredentialsValidatorOptions.cs b/src/modules/Elsa.Studio.Login/Models/OAuth2CredentialsValidatorOptions.cs new file mode 100644 index 0000000..d898541 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Models/OAuth2CredentialsValidatorOptions.cs @@ -0,0 +1,29 @@ +namespace Elsa.Studio.Login.Models; + +/// +/// Represents configuration options for the OAuth2 credentials validation process. +/// +public class OAuth2CredentialsValidatorOptions +{ + /// + /// The URL of the OAuth2 token endpoint. + /// + public string TokenEndpoint { get; set; } = string.Empty; + + /// + /// The client ID to use for the OAuth2 client. + /// + public string ClientId { get; set; } = string.Empty; + + /// + /// The client secret to use for the OAuth2 client (if confidential). + /// + public string? ClientSecret { get; set; } + + /// + /// The scope of access being requested during the OAuth2 authentication process. + /// Typically, this defines the permissions or resources the client is requesting + /// authorization for. + /// + public string? Scope { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Models/OpenIdConnectConfiguration.cs b/src/modules/Elsa.Studio.Login/Models/OpenIdConnectConfiguration.cs new file mode 100644 index 0000000..dfd9436 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Models/OpenIdConnectConfiguration.cs @@ -0,0 +1,32 @@ +namespace Elsa.Studio.Login.Models; + +/// +/// Provides configuration necessary for correct OpenIdConnect operation +/// +public class OpenIdConnectConfiguration +{ + /// + /// The authorization_endpoint as given by the openid-configuration + /// + public required string AuthEndpoint { get; set; } + + /// + /// The token_endpoint as given by the openid-configuration + /// + public required string TokenEndpoint { get; set; } + + /// + /// The end_session_endpoint as given by the openid-configuration + /// + public required string EndSessionEndpoint { get; set; } + + /// + /// The client_id as which this application is registered with the authorization server + /// + public required string ClientId { get; set; } + + /// + /// The scopes to request, defaulting to: openid profile offline_access + /// + public string[] Scopes { get; set; } = ["openid", "profile", "offline_access"]; +} diff --git a/src/modules/Elsa.Studio.Login/Models/TokenResponse.cs b/src/modules/Elsa.Studio.Login/Models/TokenResponse.cs new file mode 100644 index 0000000..7673cec --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Models/TokenResponse.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace Elsa.Studio.Login.Models; + +public sealed class TokenResponse +{ + [JsonPropertyName("access_token")] public string? AccessToken { get; set; } + [JsonPropertyName("id_token")] public string? IdToken { get; set; } + [JsonPropertyName("refresh_token")] public string? RefreshToken { get; set; } + [JsonPropertyName("expires_in")] public int ExpiresIn { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Models/ValidateCredentialsResult.cs b/src/modules/Elsa.Studio.Login/Models/ValidateCredentialsResult.cs new file mode 100644 index 0000000..cd3440c --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Models/ValidateCredentialsResult.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Login.Models; + +public record ValidateCredentialsResult(bool IsAuthenticated, string? AccessToken, string? RefreshToken); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor b/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor new file mode 100644 index 0000000..def8671 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor @@ -0,0 +1,35 @@ +@page "/login" +@inherits StudioComponentBase +@layout BasicLayout + +@* *@ \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor.cs b/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor.cs new file mode 100644 index 0000000..989725f --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor.cs @@ -0,0 +1,77 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Pages.Login.Models; +using Elsa.Studio.Login.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.WebUtilities; +using MudBlazor; + +namespace Elsa.Studio.Login.Pages.Login; + +/// +/// The login page. +/// +[AllowAnonymous] +public partial class Login +{ + private readonly LoginModel _model = new(); + + [Inject] private IJwtAccessor JwtAccessor { get; set; } = default!; + [Inject] private ICredentialsValidator CredentialsValidator { get; set; } = default!; + [Inject] private NavigationManager NavigationManager { get; set; } = default!; + [Inject] private ISnackbar Snackbar { get; set; } = default!; + [Inject] private AuthenticationStateProvider AuthenticationStateProvider { get; set; } = default!; + [Inject] private IClientInformationProvider ClientInformationProvider { get; set; } = default!; + [Inject] private IServerInformationProvider ServerInformationProvider { get; set; } = default!; + + private string ClientVersion { get; set; } = "3.0.0"; + private string ServerVersion { get; set; } = "3.0.0"; + + /// + protected override async Task OnInitializedAsync() + { + var clientInformation = await ClientInformationProvider.GetInfoAsync(); + var serverInformation = await ServerInformationProvider.GetInfoAsync(); + ClientVersion = clientInformation.PackageVersion; + ServerVersion = string.Join('.', serverInformation.PackageVersion.Split('.').Take(2)); + } + + private async Task TryLogin() + { + var isValid = await ValidateCredentials(_model.Username, _model.Password); + if (!isValid) + { + Snackbar.Add("Invalid credentials. Please try again", Severity.Error); + return; + } + + ((AccessTokenAuthenticationStateProvider)AuthenticationStateProvider).NotifyAuthenticationStateChanged(); + + var uri = new Uri(NavigationManager.Uri); + if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("returnUrl", out var returnUrl)) + { + NavigationManager.NavigateTo(returnUrl.FirstOrDefault() ?? "", true); + } + else + { + NavigationManager.NavigateTo("", true); + } + } + + private async Task ValidateCredentials(string username, string password) + { + if (string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password)) + return false; + + var result = await CredentialsValidator.ValidateCredentialsAsync(username, password); + + if (!result.IsAuthenticated) + return false; + + await JwtAccessor.WriteTokenAsync(TokenNames.AccessToken, result.AccessToken!); + await JwtAccessor.WriteTokenAsync(TokenNames.RefreshToken, result.RefreshToken!); + return true; + } +} diff --git a/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor.css b/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor.css new file mode 100644 index 0000000..29bb79a --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Pages/Login/Login.razor.css @@ -0,0 +1,8 @@ +h2.LoginTitle { + text-align: center; + text-transform: uppercase; + font-family: 'Grandstander', cursive; + font-size: 60px; + color: #ffffff; + opacity: 0.8; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Pages/Login/Models/LoginModel.cs b/src/modules/Elsa.Studio.Login/Pages/Login/Models/LoginModel.cs new file mode 100644 index 0000000..aa852b0 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Pages/Login/Models/LoginModel.cs @@ -0,0 +1,8 @@ +namespace Elsa.Studio.Login.Pages.Login.Models; + +internal class LoginModel +{ + public string Username { get; set; } = default!; + public string Password { get; set; } = default!; + public bool RememberMe { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Services/AccessTokenAuthenticationStateProvider.cs b/src/modules/Elsa.Studio.Login/Services/AccessTokenAuthenticationStateProvider.cs new file mode 100644 index 0000000..b82df40 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/AccessTokenAuthenticationStateProvider.cs @@ -0,0 +1,45 @@ +using Elsa.Studio.Extensions; +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Models; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.Extensions.Options; +using System.Security.Claims; + +namespace Elsa.Studio.Login.Services; + +/// +/// Provides the authentication state for the current user based on an access token. +/// +public class AccessTokenAuthenticationStateProvider(IJwtAccessor jwtAccessor, IJwtParser jwtParser, IOptions options) : AuthenticationStateProvider +{ + /// + public override async Task GetAuthenticationStateAsync() + { + var authToken = await jwtAccessor.ReadTokenAsync(TokenNames.IdToken) + ?? await jwtAccessor.ReadTokenAsync(TokenNames.AccessToken); + + if (string.IsNullOrEmpty(authToken)) + return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); + + var claims = jwtParser.Parse(authToken).ToList(); + var isExpired = claims.IsExpired(); + + // If the token has expired, return an empty authentication state. + if (isExpired) + return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); + + // Otherwise, return the authentication state. + var identity = new ClaimsIdentity(claims, "jwt", options.Value.NameClaimType, options.Value.RoleClaimType); + var user = new ClaimsPrincipal(identity); + + return new AuthenticationState(user); + } + + /// + /// Notifies the authentication state has changed. + /// + public void NotifyAuthenticationStateChanged() + { + NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Services/ElsaIdentityAuthorizationService.cs b/src/modules/Elsa.Studio.Login/Services/ElsaIdentityAuthorizationService.cs new file mode 100644 index 0000000..f988890 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/ElsaIdentityAuthorizationService.cs @@ -0,0 +1,30 @@ +using Elsa.Studio.Login.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Login.Services; + +/// +internal class ElsaIdentityAuthorizationService(NavigationManager NavigationManager) : IAuthorizationService +{ + /// + public Task RedirectToAuthorizationServer() + { + var returnUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri); + if (string.IsNullOrWhiteSpace(returnUrl)) + { + NavigationManager.NavigateTo("login", true); + } + else + { + NavigationManager.NavigateTo($"login?returnUrl={returnUrl}", true); + } + + return Task.CompletedTask; + } + + /// + public Task ReceiveAuthorizationCode(string code, string? state, CancellationToken cancellationToken) + { + throw new NotSupportedException(); + } +} diff --git a/src/modules/Elsa.Studio.Login/Services/ElsaIdentityCredentialsValidator.cs b/src/modules/Elsa.Studio.Login/Services/ElsaIdentityCredentialsValidator.cs new file mode 100644 index 0000000..3024508 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/ElsaIdentityCredentialsValidator.cs @@ -0,0 +1,33 @@ +using Elsa.Api.Client.Resources.Identity.Contracts; +using Elsa.Api.Client.Resources.Identity.Requests; +using Elsa.Studio.Contracts; +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Models; + +namespace Elsa.Studio.Login.Services; + +/// +/// A implementation of that consumes the endpoints from Elsa.Identity. +/// +public class ElsaIdentityCredentialsValidator : ICredentialsValidator +{ + private readonly IBackendApiClientProvider _backendApiClientProvider; + /// + /// Initializes a new instance of the class. + /// + public ElsaIdentityCredentialsValidator(IBackendApiClientProvider backendApiClientProvider) + { + _backendApiClientProvider = backendApiClientProvider; + } + + /// + public async ValueTask ValidateCredentialsAsync(string username, string password, CancellationToken cancellationToken = default) + { + var api = await _backendApiClientProvider.GetApiAsync(cancellationToken); + + var request = new LoginRequest(username, password); + var response = await api.LoginAsync(request, cancellationToken); + + return new ValidateCredentialsResult(response.IsAuthenticated, response.AccessToken, response.RefreshToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Services/ElsaIdentityEndSessionService.cs b/src/modules/Elsa.Studio.Login/Services/ElsaIdentityEndSessionService.cs new file mode 100644 index 0000000..fddd19c --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/ElsaIdentityEndSessionService.cs @@ -0,0 +1,16 @@ +using Elsa.Studio.Login.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Login.Services; + +/// +public class ElsaIdentityEndSessionService(IJwtAccessor jwtAccessor, NavigationManager navigationManager) : IEndSessionService +{ + /// + public async Task LogoutAsync() + { + await jwtAccessor.WriteTokenAsync(TokenNames.AccessToken, ""); + await jwtAccessor.WriteTokenAsync(TokenNames.RefreshToken, ""); + navigationManager.NavigateTo("/", true); + } +} diff --git a/src/modules/Elsa.Studio.Login/Services/ElsaIdentityRefreshTokenService.cs b/src/modules/Elsa.Studio.Login/Services/ElsaIdentityRefreshTokenService.cs new file mode 100644 index 0000000..8b08049 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/ElsaIdentityRefreshTokenService.cs @@ -0,0 +1,40 @@ +using Elsa.Api.Client.Resources.Identity.Responses; +using Elsa.Studio.Contracts; +using Elsa.Studio.Login.Contracts; +using System.Net; +using System.Net.Http.Json; + +namespace Elsa.Studio.Login.Services; + +/// +public class ElsaIdentityRefreshTokenService(IRemoteBackendAccessor remoteBackendAccessor, IJwtAccessor jwtAccessor, HttpClient httpClient) : IRefreshTokenService +{ + /// + public async Task RefreshTokenAsync(CancellationToken cancellationToken) + { + // Get refresh token. + var refreshToken = await jwtAccessor.ReadTokenAsync(TokenNames.RefreshToken); + + // Setup request to get new tokens. + var url = remoteBackendAccessor.RemoteBackend.Url + "/identity/refresh-token"; + var refreshRequestMessage = new HttpRequestMessage(HttpMethod.Post, url); + refreshRequestMessage.Headers.Authorization = new("Bearer", refreshToken); + + // Send request. + var response = await httpClient.SendAsync(refreshRequestMessage, cancellationToken); + + // If the refresh token is invalid, we can't do anything. + if (response.StatusCode == HttpStatusCode.Unauthorized) + return new(false, null, null); + + // Parse response into tokens. + var tokens = (await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken))!; + + // Store tokens. + await jwtAccessor.WriteTokenAsync(TokenNames.RefreshToken, tokens.RefreshToken!); + await jwtAccessor.WriteTokenAsync(TokenNames.AccessToken, tokens.AccessToken!); + + // Return tokens. + return tokens; + } +} diff --git a/src/modules/Elsa.Studio.Login/Services/OAuth2CredentialsValidator.cs b/src/modules/Elsa.Studio.Login/Services/OAuth2CredentialsValidator.cs new file mode 100644 index 0000000..742fcc1 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/OAuth2CredentialsValidator.cs @@ -0,0 +1,24 @@ +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Models; +using Microsoft.Extensions.Options; + +namespace Elsa.Studio.Login.Services; + +/// +/// Validates OAuth2 credentials using a token endpoint, client ID, and optional client secret. +/// +public class OAuth2CredentialsValidator(IOptions options, OAuth2HttpClient httpClient) : ICredentialsValidator +{ + /// + public async ValueTask ValidateCredentialsAsync(string username, string password, CancellationToken cancellationToken = default) + { + var tokenResponse = await httpClient.RequestTokenAsync(username, password, cancellationToken); + + // If the access token is null or empty, the validation failed. + if (string.IsNullOrEmpty(tokenResponse.AccessToken)) + return new(false, null, null); + + // Return the result with the access token and refresh token. + return new(true, tokenResponse.AccessToken, tokenResponse.RefreshToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Services/OAuth2HttpClient.cs b/src/modules/Elsa.Studio.Login/Services/OAuth2HttpClient.cs new file mode 100644 index 0000000..2e85731 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/OAuth2HttpClient.cs @@ -0,0 +1,45 @@ +using System.Net.Http.Json; +using Elsa.Studio.Login.Models; +using Microsoft.Extensions.Options; + +namespace Elsa.Studio.Login.Services; + +/// +/// Provides functionality for interacting with an OAuth2 token endpoint to request tokens. +/// +public class OAuth2HttpClient(HttpClient httpClient, IOptions options) +{ + private readonly OAuth2CredentialsValidatorOptions _options = options.Value; + + /// + /// Sends a token request to the OAuth2 token endpoint using the specified credentials. + /// + /// The username to authenticate with. + /// The password to authenticate with. + /// A cancellation token used to cancel the operation. + /// A containing the access token, refresh token, and other token details. + /// Thrown when the response cannot be read or contains no valid data. + public async Task RequestTokenAsync(string username, string password, CancellationToken cancellationToken = default) + { + var request = new HttpRequestMessage(HttpMethod.Post, _options.TokenEndpoint); + var content = new Dictionary + { + { "grant_type", "password" }, + { "username", username }, + { "password", password }, + { "client_id", _options.ClientId }, + }; + + if (!string.IsNullOrEmpty(_options.ClientSecret)) content["client_secret"] = _options.ClientSecret; + if (!string.IsNullOrEmpty(_options.Scope)) content["scope"] = _options.Scope; + + request.Content = new FormUrlEncodedContent(content); + + var response = await httpClient.SendAsync(request, cancellationToken); + + if (!response.IsSuccessStatusCode) + return new(); + + return await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken) ?? throw new InvalidOperationException("Failed to read token response."); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Login/Services/OpenIdConnectAuthorizationService.cs b/src/modules/Elsa.Studio.Login/Services/OpenIdConnectAuthorizationService.cs new file mode 100644 index 0000000..c2857cd --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/OpenIdConnectAuthorizationService.cs @@ -0,0 +1,61 @@ +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Models; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.WebUtilities; +using Microsoft.Extensions.Options; +using System.Net; +using System.Net.Http.Json; +using System.Text; + +namespace Elsa.Studio.Login.Services; + +/// +public class OpenIdConnectAuthorizationService(IJwtAccessor jwtAccessor, IOptions configuration, NavigationManager navigationManager, HttpClient httpClient) : IAuthorizationService +{ + /// + public Task RedirectToAuthorizationServer() + { + var config = configuration.Value; + var redirectUri = new Uri(navigationManager.Uri).GetLeftPart(UriPartial.Authority) + "/signin-oidc"; + string url = config.AuthEndpoint + $"?client_id={WebUtility.UrlEncode(config.ClientId)}&redirect_uri={WebUtility.UrlEncode(redirectUri)}&response_type=code&scope={WebUtility.UrlEncode(String.Join(' ', config.Scopes))}"; + if (navigationManager.ToBaseRelativePath(navigationManager.Uri) is { } returnUrl and not "/") + { + url += "&state=" + WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(returnUrl)); + } + + navigationManager.NavigateTo(url, true); + return Task.CompletedTask; + } + + /// + public async Task ReceiveAuthorizationCode(string code, string? state, CancellationToken cancellationToken) + { + var config = configuration.Value; + var redirectUri = new Uri(navigationManager.Uri).GetLeftPart(UriPartial.Authority) + "/signin-oidc"; + + var refreshRequestMessage = new HttpRequestMessage(HttpMethod.Post, config.TokenEndpoint); + refreshRequestMessage.Content = new FormUrlEncodedContent( + [ + new KeyValuePair("client_id", config.ClientId), + new KeyValuePair("code", code), + new KeyValuePair("grant_type", "authorization_code"), + new KeyValuePair("redirect_uri", redirectUri), + ]); + + // Send request. + var response = await httpClient.SendAsync(refreshRequestMessage, cancellationToken); + + var tokens = (await response.Content.ReadFromJsonAsync(cancellationToken))!; + + await jwtAccessor.WriteTokenAsync(TokenNames.RefreshToken, tokens.RefreshToken ?? ""); + await jwtAccessor.WriteTokenAsync(TokenNames.AccessToken, tokens.AccessToken ?? ""); + await jwtAccessor.WriteTokenAsync(TokenNames.IdToken, tokens.IdToken ?? ""); + + string returnUrl = "/"; + if (!String.IsNullOrWhiteSpace(state)) + { + returnUrl = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(state)); + } + navigationManager.NavigateTo(returnUrl, true); + } +} diff --git a/src/modules/Elsa.Studio.Login/Services/OpenIdConnectEndSessionService.cs b/src/modules/Elsa.Studio.Login/Services/OpenIdConnectEndSessionService.cs new file mode 100644 index 0000000..fe09bfd --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/OpenIdConnectEndSessionService.cs @@ -0,0 +1,31 @@ +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Models; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Options; +using System.Net; + +namespace Elsa.Studio.Login.Services; + +/// +public class OpenIdConnectEndSessionService(IOptions options, IJwtAccessor jwtAccessor, NavigationManager navigationManager) : IEndSessionService +{ + /// + public async Task LogoutAsync() + { + await jwtAccessor.WriteTokenAsync(TokenNames.AccessToken, ""); + await jwtAccessor.WriteTokenAsync(TokenNames.RefreshToken, ""); + + string logoutUrl = "/"; + if (options.Value.EndSessionEndpoint is { } endSessionEndpoint) + { + logoutUrl = endSessionEndpoint + $"?post_logout_redirect_uri={WebUtility.UrlEncode(new Uri(navigationManager.Uri).GetLeftPart(UriPartial.Authority))}"; + if (await jwtAccessor.ReadTokenAsync(TokenNames.IdToken) is { } idToken && !String.IsNullOrWhiteSpace(idToken)) + { + logoutUrl += $"&id_token_hint={WebUtility.UrlEncode(idToken)}"; + } + } + + await jwtAccessor.WriteTokenAsync(TokenNames.IdToken, ""); + navigationManager.NavigateTo(logoutUrl, true); + } +} diff --git a/src/modules/Elsa.Studio.Login/Services/OpenIdConnectRefreshTokenService.cs b/src/modules/Elsa.Studio.Login/Services/OpenIdConnectRefreshTokenService.cs new file mode 100644 index 0000000..9b6c558 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/Services/OpenIdConnectRefreshTokenService.cs @@ -0,0 +1,47 @@ +using Elsa.Api.Client.Resources.Identity.Responses; +using Elsa.Studio.Login.Contracts; +using Elsa.Studio.Login.Models; +using Microsoft.Extensions.Options; +using System.Net.Http.Json; + +namespace Elsa.Studio.Login.Services; + +/// +public class OpenIdConnectRefreshTokenService(IOptions options, IJwtAccessor jwtAccessor, HttpClient httpClient) : IRefreshTokenService +{ + /// + public async Task RefreshTokenAsync(CancellationToken cancellationToken) + { + // Get refresh token. + var refreshToken = await jwtAccessor.ReadTokenAsync(TokenNames.RefreshToken); + if (refreshToken == null) + return new(false, null, null); + + // Setup request to get new tokens. + var refreshRequestMessage = new HttpRequestMessage(HttpMethod.Post, options.Value.TokenEndpoint); + refreshRequestMessage.Content = new FormUrlEncodedContent( + [ + new KeyValuePair("client_id", options.Value.ClientId), + new KeyValuePair("grant_type", "refresh_token"), + new KeyValuePair("refresh_token", refreshToken), + ]); + + // Send request. + var response = await httpClient.SendAsync(refreshRequestMessage, cancellationToken); + + // If the refresh token is invalid, we can't do anything. + if (!response.IsSuccessStatusCode) + return new(false, null, null); + + // Parse response into tokens. + var tokens = (await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken))!; + + // Store tokens. + await jwtAccessor.WriteTokenAsync(TokenNames.RefreshToken, tokens.RefreshToken ?? ""); + await jwtAccessor.WriteTokenAsync(TokenNames.AccessToken, tokens.AccessToken ?? ""); + await jwtAccessor.WriteTokenAsync(TokenNames.IdToken, tokens.IdToken ?? ""); + + // Return tokens. + return new(tokens.AccessToken != null, tokens.AccessToken, tokens.RefreshToken); + } +} diff --git a/src/modules/Elsa.Studio.Login/_Imports.razor b/src/modules/Elsa.Studio.Login/_Imports.razor new file mode 100644 index 0000000..9946f63 --- /dev/null +++ b/src/modules/Elsa.Studio.Login/_Imports.razor @@ -0,0 +1,7 @@ +@using System.ComponentModel.DataAnnotations +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Forms +@using MudBlazor +@using Elsa.Studio.Components +@using Elsa.Studio.Layouts \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/Client/ISecretsApi.cs b/src/modules/Elsa.Studio.Secrets/Client/ISecretsApi.cs new file mode 100644 index 0000000..b3594b5 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/Client/ISecretsApi.cs @@ -0,0 +1,47 @@ +using Elsa.Api.Client.Shared.Models; +using Elsa.Secrets; +using Elsa.Secrets.BulkActions; +using Elsa.Secrets.UniqueName; +using Refit; + +namespace Elsa.Studio.Secrets.Client; + +/// Represents a client API for managing secrets. +public interface ISecretsApi +{ + /// Lists all secrets. + [Get("/secrets")] + Task> ListAsync(CancellationToken cancellationToken = default); + + /// Gets a secret by ID. + [Get("/secrets/{id}")] + Task GetAsync(string id, CancellationToken cancellationToken = default); + + /// Gets a secret input model by ID. + [Get("/secrets/{id}/input")] + Task GetInputAsync(string id, CancellationToken cancellationToken = default); + + /// Generates a unique name for a secret. + [Post("/actions/secrets/generate-unique-name")] + Task GenerateUniqueNameAsync(CancellationToken cancellationToken = default); + + /// Checks if a name is unique for a secret. + [Post("/queries/secrets/is-unique-name")] + Task GetIsNameUniqueAsync(IsUniqueNameRequest request, CancellationToken cancellationToken); + + /// Creates a new secret. + [Post("/secrets")] + Task CreateAsync(SecretInputModel request, CancellationToken cancellationToken = default); + + /// Updates a secret. + [Post("/secrets/{id}")] + Task UpdateAsync(string id, SecretInputModel request, CancellationToken cancellationToken = default); + + /// Deletes a secret. + [Delete("/secrets/{id}")] + Task DeleteAsync(string id, CancellationToken cancellationToken = default); + + /// Deletes multiple secrets. + [Post("/bulk-actions/secrets/delete")] + Task BulkDeleteAsync(BulkDeleteRequest request, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/Elsa.Studio.Secrets.csproj b/src/modules/Elsa.Studio.Secrets/Elsa.Studio.Secrets.csproj new file mode 100644 index 0000000..72ddd77 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/Elsa.Studio.Secrets.csproj @@ -0,0 +1,21 @@ + + + + Adds secrets management to the studio. + elsa studio module + + + + + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Secrets/Elsa.Studio.Secrets.csproj.DotSettings b/src/modules/Elsa.Studio.Secrets/Elsa.Studio.Secrets.csproj.DotSettings new file mode 100644 index 0000000..17962b1 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/Elsa.Studio.Secrets.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Secrets/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..f5b8ecf --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Models; +using Elsa.Studio.Secrets.Client; +using Elsa.Studio.Secrets.Menu; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Secrets; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the Secrets module. + /// + public static IServiceCollection AddSecretsModule(this IServiceCollection services, BackendApiConfig backendApiConfig) + { + return services + .AddScoped() + .AddScoped() + .AddRemoteApi(backendApiConfig); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/Extensions/TimeSpanExtensions.cs b/src/modules/Elsa.Studio.Secrets/Extensions/TimeSpanExtensions.cs new file mode 100644 index 0000000..a465b2e --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/Extensions/TimeSpanExtensions.cs @@ -0,0 +1,30 @@ +namespace Elsa.Studio.Secrets; + +/// +/// Provides extension methods for objects. +/// +public static class TimeSpanExtensions +{ + /// + /// Converts objects to a simple human-readable string. Examples: 3.1 seconds, 2 minutes, 4.23 hours, etc. + /// + /// The timespan. + /// Significant digits to use for output. + /// + public static string ToHumanTimeString(this TimeSpan span, int significantDigits = 3) + { + if(span <= TimeSpan.Zero) + return "0"; + + var format = "G" + significantDigits; + return span.TotalMilliseconds < 1000 + ? span.TotalMilliseconds.ToString(format) + " milliseconds" + : span.TotalSeconds < 60 + ? (int)span.TotalSeconds + " seconds" + : span.TotalMinutes < 60 + ? (int)span.TotalMinutes + " minutes" + : span.TotalHours < 24 + ? (int)span.TotalHours + " hours" + : (int)span.TotalDays + " days"; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/FodyWeavers.xml b/src/modules/Elsa.Studio.Secrets/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/FodyWeavers.xsd b/src/modules/Elsa.Studio.Secrets/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/Menu/SecretsMenu.cs b/src/modules/Elsa.Studio.Secrets/Menu/SecretsMenu.cs new file mode 100644 index 0000000..d0a4348 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/Menu/SecretsMenu.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.Models; +using MudBlazor; + +namespace Elsa.Studio.Secrets.Menu; + +/// +/// Provides the menu items for the Secrets module. +/// +public class SecretsMenu(ILocalizer localizer) : IMenuProvider +{ + /// + public ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default) + { + var menuItems = new List + { + new() + { + Icon = Icons.Material.Filled.Key, + Href = "secrets", + Text = localizer["Secrets"], + GroupName = MenuItemGroups.Settings.Name + } + }; + + return new ValueTask>(menuItems); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/Module.cs b/src/modules/Elsa.Studio.Secrets/Module.cs new file mode 100644 index 0000000..112ea3c --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/Module.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Abstractions; + +namespace Elsa.Studio.Secrets; + +public class Feature : FeatureBase +{ + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/UI/Components/CreateSecretDialog.razor b/src/modules/Elsa.Studio.Secrets/UI/Components/CreateSecretDialog.razor new file mode 100644 index 0000000..0d37f4a --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/UI/Components/CreateSecretDialog.razor @@ -0,0 +1,34 @@ +@using Variant = MudBlazor.Variant +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + + + + + + + + + + @Localizer["General"] + @Localizer["API Keys"] + @Localizer["Connection Strings"] + + + @Localizer["7 days"] + @Localizer["14 days"] + @Localizer["30 days"] + @Localizer["90 days"] + @Localizer["180 days"] + @Localizer["Never"] + + + + + + + @Localizer["Cancel"] + @Localizer["Ok"] + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/UI/Components/CreateSecretDialog.razor.cs b/src/modules/Elsa.Studio.Secrets/UI/Components/CreateSecretDialog.razor.cs new file mode 100644 index 0000000..ae01ef9 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/UI/Components/CreateSecretDialog.razor.cs @@ -0,0 +1,54 @@ +using Blazored.FluentValidation; +using Elsa.Secrets; +using Elsa.Studio.Contracts; +using Elsa.Studio.Secrets.Client; +using Elsa.Studio.Secrets.UI.Validators; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using MudBlazor; + +namespace Elsa.Studio.Secrets.UI.Components; + +/// A dialog that creates a new secret. +public partial class CreateSecretDialog +{ + private readonly SecretInputModel _inputModel = new(); + private EditContext _editContext = null!; + private FluentValidationValidator _fluentValidationValidator = null!; + private SecretInputModelValidator _validator = null!; + + /// The default name of the agent to create. + [Parameter] public string SecretName { get; set; } = ""; + [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!; + [Inject] private IBackendApiClientProvider ApiClientProvider { get; set; } = null!; + + /// + protected override async Task OnInitializedAsync() + { + _inputModel.Name = SecretName; + _inputModel.Description = ""; + _editContext = new(_inputModel); + var api = await ApiClientProvider.GetApiAsync(); + _validator = new(api); + } + + private Task OnCancelClicked() + { + MudDialog.Cancel(); + return Task.CompletedTask; + } + + private async Task OnSubmitClicked() + { + if(!await _fluentValidationValidator.ValidateAsync()) + return; + + await OnValidSubmit(); + } + + private Task OnValidSubmit() + { + MudDialog.Close(_inputModel); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/UI/Pages/Secret.razor b/src/modules/Elsa.Studio.Secrets/UI/Pages/Secret.razor new file mode 100644 index 0000000..a5e75b2 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/UI/Pages/Secret.razor @@ -0,0 +1,68 @@ +@page "/secrets/{SecretId}" +@using Elsa.Secrets +@using Variant = MudBlazor.Variant +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +@Localizer["Secret"] + + + + + + + + + + + + + + + + @Localizer["7 days"] + @Localizer["14 days"] + @Localizer["30 days"] + @Localizer["90 days"] + @Localizer["180 days"] + @Localizer["Never"] + + + + @Localizer["General"] + @Localizer["API Keys"] + @Localizer["Connection Strings"] + + + + + + + + + @Localizer["Save"] + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/UI/Pages/Secret.razor.cs b/src/modules/Elsa.Studio.Secrets/UI/Pages/Secret.razor.cs new file mode 100644 index 0000000..39f8800 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/UI/Pages/Secret.razor.cs @@ -0,0 +1,51 @@ +using Elsa.Secrets; +using Elsa.Studio.Components; +using Elsa.Studio.Contracts; +using Elsa.Studio.Secrets.Client; +using Elsa.Studio.Secrets.UI.Validators; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Secrets.UI.Pages; + +public partial class Secret : StudioComponentBase +{ + /// The ID of the secret to edit. + [Parameter] public string SecretId { get; set; } = default!; + + [Inject] private IBackendApiClientProvider ApiClientProvider { get; set; } = default!; + [Inject] private ISnackbar Snackbar { get; set; } = default!; + [Inject] private NavigationManager NavigationManager { get; set; } = default!; + + private MudForm _form = default!; + private SecretInputModelValidator _validator = default!; + private SecretInputModel _model = new(); + + /// + protected override async Task OnInitializedAsync() + { + var apiClient = await ApiClientProvider.GetApiAsync(); + _validator = new SecretInputModelValidator(apiClient); + } + + /// + protected override async Task OnParametersSetAsync() + { + var apiClient = await ApiClientProvider.GetApiAsync(); + _model = await apiClient.GetInputAsync(SecretId); + } + + private async Task OnSaveClicked() + { + await _form.Validate(); + + if (!_form.IsValid) + return; + + var apiClient = await ApiClientProvider.GetApiAsync(); + await apiClient.UpdateAsync(SecretId, _model); + Snackbar.Add("Secret successfully updated.", Severity.Success); + StateHasChanged(); + NavigationManager.NavigateTo("secrets"); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/UI/Pages/Secrets.razor b/src/modules/Elsa.Studio.Secrets/UI/Pages/Secrets.razor new file mode 100644 index 0000000..a20062d --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/UI/Pages/Secrets.razor @@ -0,0 +1,90 @@ +@page "/secrets" +@using Elsa.Secrets +@using Elsa.Studio.Secrets +@using Variant = MudBlazor.Variant +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@code +{ + private DateTime _now = DateTime.UtcNow; +} + +@Localizer["Secrets"] + + + + + + + + @Localizer["Delete"] + + + + + @Localizer["Create Secret"] + + + + + + + + + + + + + @Localizer["Name"] + + + @Localizer["Scope"] + + + @Localizer["Version"] + + + @Localizer["Status"] + + + @Localizer["Expires"] + + + + + @context.Name + @(context.Scope ?? "-") + @context.Version + @context.Status + @(context.ExpiresAt == null ? "Never" : (context.ExpiresAt!.Value - _now).ToHumanTimeString(3)) + + + @Localizer["Edit"] + @Localizer["Delete"] + + + + + @Localizer["No secrets found"] + + + @Localizer["Loading"]... + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/UI/Pages/Secrets.razor.cs b/src/modules/Elsa.Studio.Secrets/UI/Pages/Secrets.razor.cs new file mode 100644 index 0000000..b58e990 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/UI/Pages/Secrets.razor.cs @@ -0,0 +1,126 @@ +using Elsa.Secrets; +using Elsa.Secrets.BulkActions; +using Elsa.Studio.Contracts; +using Elsa.Studio.DomInterop.Contracts; +using Elsa.Studio.Secrets.Client; +using Elsa.Studio.Secrets.UI.Components; +using JetBrains.Annotations; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Secrets.UI.Pages; + +[UsedImplicitly] +public partial class Secrets +{ + private MudTable _table = null!; + private HashSet _selectedRows = new(); + + [Inject] private IDialogService DialogService { get; set; } = default!; + [Inject] private ISnackbar Snackbar { get; set; } = default!; + [Inject] NavigationManager NavigationManager { get; set; } = default!; + [Inject] private IBackendApiClientProvider ApiClientProvider { get; set; } = default!; + + private async Task GetApiAsync() + { + return await ApiClientProvider.GetApiAsync(); + } + + private async Task> ServerReload(TableState state, CancellationToken cancellationToken) + { + var apiClient = await GetApiAsync(); + var secrets = await apiClient.ListAsync(cancellationToken); + + return new TableData + { + TotalItems = (int)secrets.Count, + Items = secrets.Items + }; + } + + private async Task OnCreateClicked() + { + var apiClient = await GetApiAsync(); + var uniqueNameResponse = await apiClient.GenerateUniqueNameAsync(); + var name = uniqueNameResponse.Name; + + var parameters = new DialogParameters + { + { x => x.SecretName, name } + }; + + var options = new DialogOptions + { + CloseOnEscapeKey = true, + Position = DialogPosition.Center, + CloseButton = true, + FullWidth = true, + MaxWidth = MaxWidth.Small + }; + + var dialogInstance = await DialogService.ShowAsync("New Secret", parameters, options); + var dialogResult = await dialogInstance.Result; + + if (!dialogResult!.Canceled) + { + var inputModel = (SecretInputModel)dialogResult.Data; + try + { + var model = await apiClient.CreateAsync(inputModel); + //await EditAsync(model.Id); + Reload(); + } + catch (Exception e) + { + Snackbar.Add(e.Message, Severity.Error); + } + } + } + + private async Task EditAsync(string id) + { + await InvokeAsync(() => NavigationManager.NavigateTo($"secrets/{id}")); + } + + private void Reload() + { + _table.ReloadServerData(); + } + + private async Task OnEditClicked(string definitionId) + { + await EditAsync(definitionId); + } + + private async Task OnRowClick(TableRowClickEventArgs e) + { + await EditAsync(e.Item!.Id); + } + + private async Task OnDeleteClicked(SecretModel model) + { + var result = await DialogService.ShowMessageBox("Delete Secret?", "Are you sure you want to delete this secret?", yesText: "Delete", cancelText: "Cancel"); + + if (result != true) + return; + + var id = model.Id; + var apiClient = await GetApiAsync(); + await apiClient.DeleteAsync(id); + Reload(); + } + + private async Task OnBulkDeleteClicked() + { + var result = await DialogService.ShowMessageBox("Delete Selected Secrets?", "Are you sure you want to delete the selected secrets?", yesText: "Delete", cancelText: "Cancel"); + + if (result != true) + return; + + var ids = _selectedRows.Select(x => x.Id).ToList(); + var request = new BulkDeleteRequest { Ids = ids }; + var apiClient = await GetApiAsync(); + await apiClient.BulkDeleteAsync(request); + Reload(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/UI/Validators/SecretInputModelValidator.cs b/src/modules/Elsa.Studio.Secrets/UI/Validators/SecretInputModelValidator.cs new file mode 100644 index 0000000..975d023 --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/UI/Validators/SecretInputModelValidator.cs @@ -0,0 +1,32 @@ +using Elsa.Secrets; +using Elsa.Secrets.UniqueName; +using Elsa.Studio.Contracts; +using Elsa.Studio.Secrets.Client; +using FluentValidation; + +namespace Elsa.Studio.Secrets.UI.Validators; + +/// +/// A validator for instances. +/// +public class SecretInputModelValidator : AbstractValidator +{ + /// + public SecretInputModelValidator(ISecretsApi api) + { + RuleFor(x => x.Name).NotEmpty().WithMessage("Please enter a name for the secret."); + RuleFor(x => x.Value).NotEmpty().WithMessage("Please enter the secret value."); + + RuleFor(x => x.Name) + .MustAsync(async (context, name, cancellationToken) => + { + var request = new IsUniqueNameRequest + { + Name = name!, + }; + var response = await api.GetIsNameUniqueAsync(request, cancellationToken); + return response.IsUnique; + }) + .WithMessage("A secret with this name already exists."); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Secrets/_Imports.razor b/src/modules/Elsa.Studio.Secrets/_Imports.razor new file mode 100644 index 0000000..cdf191f --- /dev/null +++ b/src/modules/Elsa.Studio.Secrets/_Imports.razor @@ -0,0 +1,12 @@ +@using Elsa.Studio.Components +@using Elsa.Studio.Localization +@using Elsa.Studio.Secrets +@using Blazored.FluentValidation +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.JSInterop +@using MudBlazor +@using MudExtensions +@attribute [Authorize] \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Security/Elsa.Studio.Security.csproj b/src/modules/Elsa.Studio.Security/Elsa.Studio.Security.csproj new file mode 100644 index 0000000..395546b --- /dev/null +++ b/src/modules/Elsa.Studio.Security/Elsa.Studio.Security.csproj @@ -0,0 +1,16 @@ + + + + Adds user and role management to the studio. + elsa studio module + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Security/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Security/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..e58885a --- /dev/null +++ b/src/modules/Elsa.Studio.Security/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,15 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Security.Menu; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Security.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddSecurityModule(this IServiceCollection services) + { + return services + .AddScoped() + .AddScoped(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Security/FodyWeavers.xml b/src/modules/Elsa.Studio.Security/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Security/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Security/FodyWeavers.xsd b/src/modules/Elsa.Studio.Security/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Security/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Security/Menu/SecurityMenu.cs b/src/modules/Elsa.Studio.Security/Menu/SecurityMenu.cs new file mode 100644 index 0000000..3ee72e4 --- /dev/null +++ b/src/modules/Elsa.Studio.Security/Menu/SecurityMenu.cs @@ -0,0 +1,39 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using MudBlazor; + +namespace Elsa.Studio.Security.Menu; + +public class SecurityMenu : IMenuProvider +{ + public ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default) + { + var menuItems = new List + { + new() + { + Icon = Icons.Material.Filled.Security, + Href = "security/users", + Text = "Security", + GroupName = MenuItemGroups.Settings.Name, + SubMenuItems = + { + new MenuItem + { + Text = "Users", + Href = "security/users", + Icon = Icons.Material.Filled.Person + }, + new MenuItem + { + Text = "Roles", + Href = "security/roles", + Icon = Icons.Material.Filled.PeopleOutline + } + } + } + }; + + return new ValueTask>(menuItems); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Security/Module.cs b/src/modules/Elsa.Studio.Security/Module.cs new file mode 100644 index 0000000..431c176 --- /dev/null +++ b/src/modules/Elsa.Studio.Security/Module.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Abstractions; + +namespace Elsa.Studio.Security; + +public class Feature : FeatureBase +{ + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Security/Pages/Roles.razor b/src/modules/Elsa.Studio.Security/Pages/Roles.razor new file mode 100644 index 0000000..753996f --- /dev/null +++ b/src/modules/Elsa.Studio.Security/Pages/Roles.razor @@ -0,0 +1,8 @@ +@page "/security/roles" +@inherits StudioComponentBase + +Roles + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Security/Pages/Users.razor b/src/modules/Elsa.Studio.Security/Pages/Users.razor new file mode 100644 index 0000000..06be0c4 --- /dev/null +++ b/src/modules/Elsa.Studio.Security/Pages/Users.razor @@ -0,0 +1,8 @@ +@page "/security/users" +@inherits StudioComponentBase + +Users + + + + diff --git a/src/modules/Elsa.Studio.Security/_Imports.razor b/src/modules/Elsa.Studio.Security/_Imports.razor new file mode 100644 index 0000000..93919a4 --- /dev/null +++ b/src/modules/Elsa.Studio.Security/_Imports.razor @@ -0,0 +1,7 @@ +@using Elsa.Studio.Components +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.JSInterop +@using MudBlazor +@attribute [Authorize] \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Cases.razor b/src/modules/Elsa.Studio.UIHints/Components/Cases.razor new file mode 100644 index 0000000..2934619 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Cases.razor @@ -0,0 +1,62 @@ +@inherits StudioComponentBase +@inject ILocalizer Localizer + + + + @Localizer["Label"] + @Localizer["Condition"] + @Localizer["Type"] + + + + @context.Label + @context.Condition + @GetExpressionTypeDisplayName(@context.ExpressionType) + + + + + + + + + + + + + + @foreach (var expressionDescriptor in GetSupportedExpressions()) + { + @expressionDescriptor.DisplayName + } + + + + + + @Localizer["Add case"] + + + + @if (Items.Any()) + { + + @Localizer["Add case"] + + } + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Cases.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/Cases.razor.cs new file mode 100644 index 0000000..c313ab6 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Cases.razor.cs @@ -0,0 +1,210 @@ +using System.Diagnostics; +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Helpers; +using Elsa.Studio.Workflows.Domain.Models; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// Renders an editor for a collection of objects. +/// +public partial class Cases +{ + private readonly string[] _uiSyntaxes = { "Literal", "Object" }; + + private SwitchCaseRecord? _caseBeingEdited; + private SwitchCaseRecord? _caseBeingAdded; + private MudTable _table = default!; + + /// + /// The context for the editor. + /// + [Parameter] + public DisplayInputEditorContext EditorContext { get; set; } = default!; + + [CascadingParameter] private ExpressionDescriptorProvider ExpressionDescriptorProvider { get; set; } = default!; + + private ICollection Items { get; set; } = new List(); + private bool DisableAddButton => _caseBeingEdited != null || _caseBeingAdded != null; + + /// + protected override void OnParametersSet() + { + Items = GetItems(); + } + + private ICollection GetItems() + { + var input = EditorContext.GetObjectValueOrDefault(); + var cases = ParseJson(input); + var caseRecords = cases.Select(Map).ToList(); + return caseRecords; + } + + private IEnumerable ParseJson(string? json) + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + return JsonParser.ParseJson(json, () => new List(), options); + } + + private IEnumerable GetSupportedExpressions() + { + return ExpressionDescriptorProvider.ListDescriptors().Where(x => !_uiSyntaxes.Contains(x.Type) && x.IsBrowsable).ToList(); + } + + private string GetDefaultExpressionType() + { + var defaultExpressionType = GetSupportedExpressions().FirstOrDefault()?.Type ?? "Literal"; + return defaultExpressionType; + } + + private SwitchCaseRecord Map(SwitchCase @case) + { + var defaultExpressionType = GetDefaultExpressionType(); + + return new() + { + Label = @case.Label, + Condition = @case.Condition.ToString(), + ExpressionType = string.IsNullOrWhiteSpace(@case.Condition.Type) ? defaultExpressionType : @case.Condition.Type, + Activity = @case.Activity + }; + } + + private SwitchCase Map(SwitchCaseRecord switchCase) + { + var expression = new Expression(switchCase.ExpressionType, switchCase.Condition); + + return new() + { + Label = switchCase.Label, + Condition = expression, + Activity = switchCase.Activity + }; + } + + private Task SaveChangesAsync() + { + var cases = Items.Select(Map).ToList(); + + return EditorContext.UpdateValueAsync(cases); + } + + private async void OnRowEditCommitted(object data) + { + _caseBeingAdded = null; + _caseBeingEdited = null; + await SaveChangesAsync(); + StateHasChanged(); + } + + private void OnRowEditPreview(object obj) + { + var @case = (SwitchCaseRecord)obj; + _caseBeingEdited = new() + { + Label = @case.Label, + Condition = @case.Condition, + ExpressionType = @case.ExpressionType + }; + + StateHasChanged(); + } + + private async void OnRowEditCancel(object obj) + { + if (_caseBeingAdded != null) + { + Items.Remove(_caseBeingAdded); + await SaveChangesAsync(); + _caseBeingAdded = null; + StateHasChanged(); + return; + } + + var @case = (SwitchCaseRecord)obj; + @case.Condition = _caseBeingEdited?.Condition ?? ""; + @case.Label = _caseBeingEdited?.Label ?? ""; + @case.ExpressionType = _caseBeingEdited?.ExpressionType ?? ""; + _caseBeingEdited = null; + StateHasChanged(); + } + + private async Task OnDeleteClicked(SwitchCaseRecord switchCase) + { + Items.Remove(switchCase); + await SaveChangesAsync(); + } + + private void OnAddClicked() + { + var @case = new SwitchCaseRecord + { + Label = $"Case {Items.Count + 1}", + Condition = "", + ExpressionType = GetDefaultExpressionType() + }; + + Items.Add(@case); + _caseBeingAdded = @case; + + // Need to do it this way, otherwise MudTable doesn't show the item in edit mode. + _ = Task.Delay(1).ContinueWith(_ => + { + InvokeAsync(() => + { + _table.SetEditingItem(@case); + StateHasChanged(); + }); + }); + } + + private string GetExpressionTypeDisplayName(string expressionType) + { + var expressionDescriptor = ExpressionDescriptorProvider.GetByType(expressionType) ?? throw new($"Could not find expression descriptor for expression type '{expressionType}'."); + return expressionDescriptor.DisplayName; + } +} + +/// +/// Represents a single case in a activity. +/// +public class SwitchCaseRecord +{ + /// + /// The label of the case. + /// + public string Label { get; set; } = string.Empty; + + /// + /// The condition of the case. + /// + public string Condition { get; set; } = string.Empty; + + [Obsolete("Use ExpressionType instead.")] + public string Syntax + { + get => ExpressionType; + set => ExpressionType = value; + } + + /// + /// The expression type of the case. + /// + public string ExpressionType { get; set; } = "Literal"; + + /// + /// When used in a activity, specifies the activity to schedule when the condition evaluates to true. + /// + public JsonObject? Activity { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/CheckList.razor b/src/modules/Elsa.Studio.UIHints/Components/CheckList.razor new file mode 100644 index 0000000..c0bf394 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/CheckList.razor @@ -0,0 +1,19 @@ +@inherits StudioComponentBase +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; +} + + + + + @foreach (var item in _checkListItems) + { + + } + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/CheckList.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/CheckList.razor.cs new file mode 100644 index 0000000..be0efb8 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/CheckList.razor.cs @@ -0,0 +1,70 @@ +using Elsa.Api.Client.Shared.UIHints.CheckList; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Extensions; +using Elsa.Studio.UIHints.Helpers; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// A component that renders a check list. +/// +public partial class CheckList +{ + private ICollection _checkListItems = []; + + /// + /// The editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + /// + protected override void OnInitialized() + { + var checkList = EditorContext.InputDescriptor.GetCheckList(); + var selectedValues = GetSelectedValues(checkList.IsFlagsEnum); + + _checkListItems = checkList.Items + .Select(i => new CheckListItem { Value = i.Value, Text = i.Text, IsChecked = selectedValues.Contains(i.Value) }) + .ToList(); + } + + private ICollection GetSelectedValues(bool isFlagsEnum) + { + var inputDescriptor = EditorContext.InputDescriptor; + var input = EditorContext.GetObjectValueOrDefault(); + var defaultValue = inputDescriptor.DefaultValue; + var json = !string.IsNullOrWhiteSpace(input) ? input : defaultValue as string; + + if (isFlagsEnum) + { + return !string.IsNullOrWhiteSpace(json) + ? int.TryParse(json, out var n) ? [n.ToString()] : Array.Empty() + : [defaultValue?.ToString() ?? string.Empty]; + } + + var selectListItems = ParseJson(json); + + if (!selectListItems.Any()) + selectListItems = ParseJson(defaultValue as string); + + return selectListItems; + } + + private ICollection ParseJson(string? json) + { + return JsonParser.ParseJson>(json, () => new List()); + } + + private async Task OnCheckedChanged(CheckListItem item, bool? state) + { + // Toggle state. + item.IsChecked = state == true; + + // Get selected values. + var selectedValues = _checkListItems.Where(x => x.IsChecked).Select(x => x.Value).ToList(); + + // Update state. + await EditorContext.UpdateValueOrObjectExpressionAsync(selectedValues); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Checkbox.razor b/src/modules/Elsa.Studio.UIHints/Components/Checkbox.razor new file mode 100644 index 0000000..3f95b92 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Checkbox.razor @@ -0,0 +1,50 @@ +@using Elsa.Studio.Models +@using Elsa.Api.Client.Resources.Scripting.Models +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var inputValue = EditorContext.GetLiteralValueOrDefault(); + var isChecked = !string.IsNullOrWhiteSpace(inputValue) && bool.TryParse(inputValue, out var b) && b; +} + + + + + + + + + +@code { + + /// + /// The editor context. + /// + [Parameter] + public DisplayInputEditorContext EditorContext { get; set; } = null!; + + private async Task OnCheckChanged(bool? isChecked) + { + if (EditorContext.InputDescriptor.IsWrapped) + { + var newValue = isChecked == true ? "True" : "False"; + var expression = Expression.CreateLiteral(newValue); + + await EditorContext.UpdateExpressionAsync(expression); + } + else + { + await EditorContext.UpdateValueAsync(isChecked); + } + } + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Code.razor b/src/modules/Elsa.Studio.UIHints/Components/Code.razor new file mode 100644 index 0000000..f9a9cf0 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Code.razor @@ -0,0 +1,21 @@ +@using BlazorMonaco.Editor +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; +} + + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Code.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/Code.razor.cs new file mode 100644 index 0000000..27b395f --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Code.razor.cs @@ -0,0 +1,130 @@ +using BlazorMonaco.Editor; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Shared.UIHints.CodeEditor; +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Extensions; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using ThrottleDebounce; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// A component that renders a code editor. +/// +public partial class Code : IDisposable +{ + private readonly string _monacoEditorId = $"monaco-editor-{Guid.NewGuid()}:N"; + private StandaloneCodeEditor? _monacoEditor; + private string _monacoLanguage = ""; + private string? _lastMonacoEditorContent; + private readonly RateLimitedFunc _throttledValueChanged; + private CodeEditorOptions _codeEditorOptions = new(); + private bool _isInternalContentChange; + + [Inject] private IJSRuntime JSRuntime { get; set; } = default!; + [Inject] private IEnumerable MonacoHandlers { get; set; } = default!; + + /// + public Code() + { + _throttledValueChanged = Debouncer.Debounce(InvokeValueChangedCallback, TimeSpan.FromMilliseconds(500)); + } + + /// + /// The context for the editor. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = default!; + + private string InputValue => EditorContext.GetLiteralValueOrDefault(); + + /// + protected override void OnInitialized() + { + _codeEditorOptions = EditorContext.InputDescriptor.GetCodeEditorOptions(); + _monacoLanguage = _codeEditorOptions.Language ?? "javascript"; + ; + } + + private StandaloneEditorConstructionOptions ConfigureMonacoEditor(StandaloneCodeEditor editor) + { + return new StandaloneEditorConstructionOptions + { + Language = _monacoLanguage, + Value = InputValue, + FontFamily = "Roboto Mono, monospace", + RenderLineHighlight = "none", + Minimap = new EditorMinimapOptions + { + Enabled = false + }, + AutomaticLayout = true, + LineNumbers = "on", + Theme = "vs", + RoundedSelection = true, + ScrollBeyondLastLine = false, + OverviewRulerLanes = 0, + OverviewRulerBorder = false, + LineDecorationsWidth = 0, + HideCursorInOverviewRuler = true, + GlyphMargin = false, + ReadOnly = EditorContext.IsReadOnly, + DomReadOnly = EditorContext.IsReadOnly + }; + } + + private async Task OnMonacoInitializedAsync() + { + _isInternalContentChange = true; + var model = await _monacoEditor!.GetModel(); + _lastMonacoEditorContent = InputValue; + await model.SetValue(InputValue); + _isInternalContentChange = false; + await Global.SetModelLanguage(JSRuntime, model, _monacoLanguage); + await RunMonacoHandlersAsync(_monacoEditor); + } + + private async Task OnMonacoContentChanged(ModelContentChangedEvent e) + { + if (_isInternalContentChange) + return; + + await _throttledValueChanged.InvokeAsync(); + } + + private async Task InvokeValueChangedCallback() + { + var value = await _monacoEditor!.GetValue(); + + // This event gets fired even when the content hasn't changed, but for example when the containing pane is resized. + // This happens from within the monaco editor itself (or the Blazor wrapper, not sure). + if (value == _lastMonacoEditorContent) + return; + + _lastMonacoEditorContent = value; + var expression = Expression.CreateLiteral(value); + + await InvokeAsync(async () => await EditorContext.UpdateExpressionAsync(expression)); + } + + private async Task RunMonacoHandlersAsync(StandaloneCodeEditor editor) + { + var customProps = new Dictionary + { + { nameof(ActivityDescriptor), EditorContext.ActivityDescriptor }, + { nameof(InputDescriptor), EditorContext.InputDescriptor }, + { "WorkflowDefinitionId", EditorContext.WorkflowDefinition.DefinitionId } + }; + + var expressionDescriptor = EditorContext.SelectedExpressionDescriptor ?? new ExpressionDescriptor("Default", "Default"); + var context = new MonacoContext(editor, expressionDescriptor, customProps); + + foreach (var handler in MonacoHandlers) + await handler.InitializeAsync(context); + } + + void IDisposable.Dispose() => _throttledValueChanged.Dispose(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/DateTimePicker.razor b/src/modules/Elsa.Studio.UIHints/Components/DateTimePicker.razor new file mode 100644 index 0000000..b18af61 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/DateTimePicker.razor @@ -0,0 +1,111 @@ +@using Elsa.Studio.Models +@using Elsa.Api.Client.Shared.UIHints.SingleLine +@using Elsa.Studio.DomInterop.Contracts +@using Elsa.Studio.UIHints.Extensions +@using System.Globalization + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = $"{inputDescriptor.DisplayName} (Date)"; + var displayTimeName = $"{inputDescriptor.DisplayName} (Time)"; +} + + + + + + + @if (showTimePicker) + { + + } + + @if (InputDateValue is not null) + { + + } + + + + +@code { + private bool showTimePicker; + private DateTime? inputDateValue; + private TimeSpan? inputTimeValue; + + public bool ShowTimePicker + { + get => showTimePicker; + set + { + showTimePicker = value; + if (showTimePicker == false) InputTimeValue = null; + } + } + public DateTime? InputDateValue + { + get => inputDateValue; + set + { + inputDateValue = value; + if (inputDateValue is null) + { + inputTimeValue = null; + showTimePicker = false; + } + OnValueChanged(); + } + } + public TimeSpan? InputTimeValue + { + get => inputTimeValue; + set + { + inputTimeValue = value; + OnValueChanged(); + } + } + + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + protected override void OnInitialized() + { + if (DateTime.TryParse(EditorContext.GetExpressionValueOrDefault(), out var parsedDate)) + { + inputDateValue = parsedDate; + inputTimeValue = parsedDate.TimeOfDay; + showTimePicker = parsedDate.TimeOfDay.Ticks != 0; + } + } + + private async Task OnValueChanged() + { + var combinedDateTime = InputDateValue?.Date.Add(InputTimeValue ?? TimeSpan.Zero); + await EditorContext.UpdateValueOrLiteralExpressionAsync(combinedDateTime?.ToString()); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Dropdown.razor b/src/modules/Elsa.Studio.UIHints/Components/Dropdown.razor new file mode 100644 index 0000000..8b32267 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Dropdown.razor @@ -0,0 +1,30 @@ +@using Elsa.Api.Client.Shared.UIHints.DropDown +@inject ILocalizer Localizer + +@inherits StudioComponentBase +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var selectedValue = GetSelectedValue(); + var searchBox = _items.Count > 10; +} + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Dropdown.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/Dropdown.razor.cs new file mode 100644 index 0000000..3d79cb5 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Dropdown.razor.cs @@ -0,0 +1,37 @@ +using Elsa.Api.Client.Shared.UIHints.DropDown; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Extensions; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// A component that renders a dropdown. +/// +public partial class Dropdown +{ + private ICollection _items = []; + + /// + /// The editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + /// + protected override void OnInitialized() + { + var selectList = EditorContext.InputDescriptor.GetSelectList(); + _items = selectList.Items.OrderBy(x => x.Text).ToList(); + } + + private SelectListItem? GetSelectedValue() + { + var value = EditorContext.GetLiteralValueOrDefault(); + return _items.FirstOrDefault(x => x.Value == value); + } + + private async Task OnValueChanged(SelectListItem? value) + { + await EditorContext.UpdateValueOrLiteralExpressionAsync(value?.Value ?? ""); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/DynamicOutcomes.razor b/src/modules/Elsa.Studio.UIHints/Components/DynamicOutcomes.razor new file mode 100644 index 0000000..abc1cd8 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/DynamicOutcomes.razor @@ -0,0 +1,30 @@ +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; +} + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/DynamicOutcomes.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/DynamicOutcomes.razor.cs new file mode 100644 index 0000000..cfa7a4e --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/DynamicOutcomes.razor.cs @@ -0,0 +1,63 @@ +using System.Reflection; +using System.Text.Json; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Studio.Converters; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Helpers; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using MudExtensions; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// Implements a component for the "dynamic-outcomes" UI hint. +/// +public partial class DynamicOutcomes +{ + private List _items = new(); + private MudChipField _chipField = default!; + + /// + /// Gets or sets the editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = default!; + + /// + protected override void OnInitialized() + { + _items = GetCurrentItems(); + } + + private List GetCurrentItems() + { + var input = EditorContext.GetObjectValueOrDefault(); + return ParseJson(input); + } + + private List ParseJson(string? json) + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + options.Converters.Add(new JsonPrimitiveToStringConverter()); + return JsonParser.ParseJson(json, () => new List(), options); + } + + private async Task OnValuesChanges(List arg) + { + await EditorContext.UpdateValueOrObjectExpressionAsync(_items); + } + + private void OnKeyDown(KeyboardEventArgs arg) + { + // TODO: This is a hack to get the chips to update when the user presses enter. + // Ideally, we can configure this on MudChipField, but this is not currently supported. + if (arg.Key is not ("Enter" or "Tab")) return; + + var setChipsMethod = _chipField.GetType().GetMethod("SetChips", BindingFlags.Instance | BindingFlags.NonPublic); + setChipsMethod!.Invoke(_chipField, null); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/ExpressionEditor.razor b/src/modules/Elsa.Studio.UIHints/Components/ExpressionEditor.razor new file mode 100644 index 0000000..5f7540c --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/ExpressionEditor.razor @@ -0,0 +1,10 @@ +@using Elsa.Studio.Models + + + +@code { + + /// Gets or sets the editor context. + [Parameter] + public DisplayInputEditorContext EditorContext { get; set; } = null!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/HttpStatusCodes.razor b/src/modules/Elsa.Studio.UIHints/Components/HttpStatusCodes.razor new file mode 100644 index 0000000..88d5594 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/HttpStatusCodes.razor @@ -0,0 +1,33 @@ +@inject ILocalizer Localizer +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; +} + + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/HttpStatusCodes.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/HttpStatusCodes.razor.cs new file mode 100644 index 0000000..9cb1f12 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/HttpStatusCodes.razor.cs @@ -0,0 +1,54 @@ +using System.Reflection; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using MudExtensions; + +namespace Elsa.Studio.UIHints.Components; + +public partial class HttpStatusCodes +{ + private List _items = new(); + private MudChipField _chipField = null!; + + /// + /// The editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + /// + protected override void OnParametersSet() + { + _items = GetCurrentItems(); + } + + private List GetCurrentItems() + { + var expectedStatusCodes = EditorContext.GetValueOrDefault>()?.ToList() ?? new List(); + return expectedStatusCodes; + } + + private async Task OnValuesChanges(List? values) + { + // Remove any item from _items that is not in values. + _items.RemoveAll(x => values?.Contains(x.StatusCode.ToString()) != true); + + // Add any item from values that is not in _items. + _items.AddRange(values? + .Where(x => _items.All(y => y.StatusCode.ToString() != x)) + .Select(x => new HttpStatusCodeCase { StatusCode = int.Parse(x) }) ?? new List()); + + await EditorContext.UpdateValueAsync(_items); + } + + private void OnKeyDown(KeyboardEventArgs arg) + { + // TODO: This is a hack to get the chips to update when the user presses enter. + // Ideally, we can configure this on MudChipField, but this is not currently supported. + if (arg.Key is not ("Enter" or "Tab")) return; + + var setChipsMethod = _chipField.GetType().GetMethod("SetChips", BindingFlags.Instance | BindingFlags.NonPublic); + setChipsMethod!.Invoke(_chipField, null); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Json.razor b/src/modules/Elsa.Studio.UIHints/Components/Json.razor new file mode 100644 index 0000000..89d5ddd --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Json.razor @@ -0,0 +1,21 @@ +@using BlazorMonaco.Editor +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; +} + + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/Json.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/Json.razor.cs new file mode 100644 index 0000000..e4fa391 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/Json.razor.cs @@ -0,0 +1,92 @@ +using BlazorMonaco.Editor; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Shared.UIHints.CodeEditor; +using Elsa.Studio.Extensions; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Extensions; +using Microsoft.AspNetCore.Components; +using ThrottleDebounce; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// A component that renders a code editor. +/// +public partial class Json : IDisposable +{ + private readonly string _monacoEditorId = $"monaco-editor-{Guid.NewGuid()}:N"; + private StandaloneCodeEditor? _monacoEditor; + private string? _lastMonacoEditorContent; + private readonly RateLimitedFunc _throttledValueChanged; + private CodeEditorOptions _codeEditorOptions = new(); + + /// + public Json() + { + _throttledValueChanged = Debouncer.Debounce(InvokeValueChangedCallback, TimeSpan.FromMilliseconds(500)); + } + + /// + /// The context for the editor. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + private string InputValue => EditorContext.GetLiteralValueOrDefault(); + + /// + protected override void OnInitialized() + { + _codeEditorOptions = EditorContext.InputDescriptor.GetCodeEditorOptions(); + } + + private StandaloneEditorConstructionOptions ConfigureMonacoEditor(StandaloneCodeEditor editor) + { + var language = _codeEditorOptions.Language ?? "javascript"; + + return new() + { + Language = language, + Value = InputValue, + FontFamily = "Roboto Mono, monospace", + RenderLineHighlight = "none", + Minimap = new() + { + Enabled = false + }, + AutomaticLayout = true, + LineNumbers = "on", + Theme = "vs", + RoundedSelection = true, + ScrollBeyondLastLine = false, + OverviewRulerLanes = 0, + OverviewRulerBorder = false, + LineDecorationsWidth = 0, + HideCursorInOverviewRuler = true, + GlyphMargin = false, + ReadOnly = EditorContext.IsReadOnly, + DomReadOnly = EditorContext.IsReadOnly + }; + } + + private async Task OnMonacoContentChanged(ModelContentChangedEvent e) + { + await _throttledValueChanged.InvokeAsync(); + } + + private async Task InvokeValueChangedCallback() + { + var value = await _monacoEditor!.GetValue(); + + // This event gets fired even when the content hasn't changed, but for example when the containing pane is resized. + // This happens from within the monaco editor itself (or the Blazor wrapper, not sure). + if (value == _lastMonacoEditorContent) + return; + + _lastMonacoEditorContent = value; + var expression = Expression.CreateLiteral(value); + + await InvokeAsync(async () => await EditorContext.UpdateExpressionAsync(expression)); + } + + void IDisposable.Dispose() => _throttledValueChanged.Dispose(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/MultiLine.razor b/src/modules/Elsa.Studio.UIHints/Components/MultiLine.razor new file mode 100644 index 0000000..18dd3f0 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/MultiLine.razor @@ -0,0 +1,40 @@ +@using Elsa.Studio.Models +@using Elsa.Studio.UIHints.Extensions +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var inputValue = EditorContext.GetLiteralValueOrDefault(); +} + + + + + + + +@code { + + /// + /// The EditorContext provided by the input UI framework. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + private async Task OnValueChanged(string newValue) + { + await EditorContext.UpdateValueOrLiteralExpressionAsync(newValue.TrimNull()); + } + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/MultiText.razor b/src/modules/Elsa.Studio.UIHints/Components/MultiText.razor new file mode 100644 index 0000000..ae876bf --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/MultiText.razor @@ -0,0 +1,32 @@ +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; +} + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/MultiText.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/MultiText.razor.cs new file mode 100644 index 0000000..be6848d --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/MultiText.razor.cs @@ -0,0 +1,63 @@ +using System.Reflection; +using System.Text.Json; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Studio.Converters; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Helpers; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using MudExtensions; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// Implements a component for the "multi-text" UI hint. +/// +public partial class MultiText +{ + private List _items = new(); + private MudChipField _chipField = null!; + + /// + /// Gets or sets the editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + /// + protected override void OnInitialized() + { + _items = GetCurrentItems(); + } + + private List GetCurrentItems() + { + var input = EditorContext.GetObjectValueOrDefault(); + return ParseJson(input); + } + + private static List ParseJson(string? json) + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + options.Converters.Add(new JsonPrimitiveToStringConverter()); + return JsonParser.ParseJson(json, () => new List(), options); + } + + private async Task OnValuesChanges(List arg) + { + await EditorContext.UpdateValueOrObjectExpressionAsync(_items); + } + + private void OnKeyDown(KeyboardEventArgs arg) + { + // TODO: This is a hack to get the chips to update when the user presses enter. + // Ideally, we can configure this on MudChipField, but this is not currently supported. + if (arg.Key is not ("Enter" or "Tab")) return; + + var setChipsMethod = _chipField.GetType().GetMethod("SetChips", BindingFlags.Instance | BindingFlags.NonPublic); + setChipsMethod!.Invoke(_chipField, null); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/OutcomePicker.razor b/src/modules/Elsa.Studio.UIHints/Components/OutcomePicker.razor new file mode 100644 index 0000000..6d06996 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/OutcomePicker.razor @@ -0,0 +1,29 @@ +@using Elsa.Api.Client.Shared.UIHints.DropDown +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var selectedValue = GetSelectedValue(); + var searchBox = _items.Count > 10; +} + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/OutcomePicker.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/OutcomePicker.razor.cs new file mode 100644 index 0000000..8c24a2f --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/OutcomePicker.razor.cs @@ -0,0 +1,38 @@ +using Elsa.Api.Client.Shared.UIHints.DropDown; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// A component that renders a dropdown for outcomes. +/// +public partial class OutcomePicker +{ + private ICollection _items = Array.Empty(); + + /// + /// The editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + private ICollection Outcomes => EditorContext.WorkflowDefinition.Outcomes; + + /// + protected override void OnParametersSet() + { + _items = Outcomes.Select(x => new SelectListItem(x, x)).OrderBy(x => x.Text).ToList(); + } + + private SelectListItem? GetSelectedValue() + { + var value = EditorContext.GetLiteralValueOrDefault(); + return _items.FirstOrDefault(x => x.Value == value); + } + + private async Task OnValueChanged(SelectListItem? value) + { + var outcome = value?.Value ?? ""; + await EditorContext.UpdateValueOrLiteralExpressionAsync(outcome); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/OutputPicker.razor b/src/modules/Elsa.Studio.UIHints/Components/OutputPicker.razor new file mode 100644 index 0000000..e2955b1 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/OutputPicker.razor @@ -0,0 +1,28 @@ +@using Elsa.Api.Client.Shared.UIHints.DropDown +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var selectedValue = GetSelectedValue(); + var searchBox = _items.Count > 10; +} + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/OutputPicker.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/OutputPicker.razor.cs new file mode 100644 index 0000000..4f74ace --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/OutputPicker.razor.cs @@ -0,0 +1,41 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.UIHints.DropDown; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// A component that renders a dropdown for outputs. +/// +public partial class OutputPicker +{ + private ICollection _items = Array.Empty(); + + /// + /// The editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + private ICollection Outputs => EditorContext.WorkflowDefinition.Outputs; + + /// + protected override void OnParametersSet() + { + var items = Outputs.Select(x => new SelectListItem(x.DisplayName, x.Name)).OrderBy(x => x.Text).ToList(); + items.Insert(0, new("(None)", "")); + _items = items; + } + + private SelectListItem? GetSelectedValue() + { + var outputName = EditorContext.GetExpressionValueOrDefault(); + return _items.FirstOrDefault(x => x.Value == outputName); + } + + private async Task OnValueChanged(SelectListItem? value) + { + var outputName = value?.Value ?? ""; + await EditorContext.UpdateValueOrLiteralExpressionAsync(outputName); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/RadioList.razor b/src/modules/Elsa.Studio.UIHints/Components/RadioList.razor new file mode 100644 index 0000000..87440d1 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/RadioList.razor @@ -0,0 +1,21 @@ +@inherits StudioComponentBase +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; +} + + + + + + @foreach (var item in _radioListItems) + { + @item?.Text + } + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/RadioList.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/RadioList.razor.cs new file mode 100644 index 0000000..6048242 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/RadioList.razor.cs @@ -0,0 +1,46 @@ +using Elsa.Api.Client.Shared.UIHints.RadioList; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Extensions; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// A component that renders a radio list. +/// +public partial class RadioList +{ + private ICollection _radioListItems = Array.Empty(); + private string? radioItem = string.Empty; + + public string _radioItem + { + get { return radioItem; } + set + { + radioItem = value; + OnValueChanged(value); + } + } + + /// + /// The editor context. + /// + [Parameter] + public DisplayInputEditorContext EditorContext { get; set; } = default!; + + /// + protected override void OnInitialized() + { + var radioList = EditorContext.InputDescriptor.GetRadioList(); + _radioListItems = radioList.Items.ToList(); + + var value = EditorContext.GetLiteralValueOrDefault(); + radioItem = _radioListItems.FirstOrDefault(x => x.Value == value)?.Value ?? ""; + } + + private async Task OnValueChanged(string? value) + { + await EditorContext.UpdateValueOrLiteralExpressionAsync(value ?? ""); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/SingleLine.razor b/src/modules/Elsa.Studio.UIHints/Components/SingleLine.razor new file mode 100644 index 0000000..7e5d76b --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/SingleLine.razor @@ -0,0 +1,72 @@ +@using Elsa.Studio.Models +@using Elsa.Api.Client.Shared.UIHints.SingleLine +@using Elsa.Studio.DomInterop.Contracts +@using Elsa.Studio.UIHints.Extensions +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var inputValue = EditorContext.GetLiteralValueOrDefault(); + var adornment = !string.IsNullOrWhiteSpace(_singleLineProps.AdornmentText) ? Adornment.Start : Adornment.None; +} + + + + + + @if (!string.IsNullOrWhiteSpace(_singleLineProps.AdornmentText)) + { + @_singleLineProps.AdornmentText + } + + + @if (_singleLineProps.EnableCopyAdornment) + { + + } + + + + + +@code { + + private SingleLineProps _singleLineProps = new(); + + /// Gets or sets the editor context. + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + [Inject] private IClipboard Clipboard { get; set; } = null!; + + /// + protected override void OnInitialized() + { + _singleLineProps = EditorContext.InputDescriptor.GetSingleLineProps(); + } + + private async Task OnValueChanged(string newValue) + { + await EditorContext.UpdateValueOrLiteralExpressionAsync(newValue.TrimWhitespace()); + } + + private async Task OnCopyClicked() + { + var value = (_singleLineProps.AdornmentText ?? string.Empty) + EditorContext.GetLiteralValueOrDefault(); + await Clipboard.CopyText(value); + } + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/TypePicker.razor b/src/modules/Elsa.Studio.UIHints/Components/TypePicker.razor new file mode 100644 index 0000000..e9f4f0d --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/TypePicker.razor @@ -0,0 +1,37 @@ +@using Elsa.Api.Client.Resources.VariableTypes.Models +@inject ILocalizer Localizer +@inherits StudioComponentBase + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var selectedValue = GetSelectedValue(); + var searchBox = _variableTypes.Count > 10; +} + + + + + @foreach (var grouping in _groupedVariableTypes) + { + + @foreach (var variableType in grouping) + { + @variableType.DisplayName + } + + } + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/TypePicker.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/TypePicker.razor.cs new file mode 100644 index 0000000..35cd23a --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/TypePicker.razor.cs @@ -0,0 +1,40 @@ +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; +using Elsa.Api.Client.Resources.VariableTypes.Models; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// Provides a component for picking a type. +/// +public partial class TypePicker +{ + private ICollection _variableTypes = new List(); + private ICollection> _groupedVariableTypes = new List>(); + + /// + /// Gets or sets the editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + [Inject] private IVariableTypeService VariableTypeService { get; set; } = null!; + + /// + protected override async Task OnParametersSetAsync() + { + _variableTypes = (await VariableTypeService.GetVariableTypesAsync()).ToList(); + _groupedVariableTypes = _variableTypes.GroupBy(x => x.Category).ToList(); + } + + private VariableTypeDescriptor? GetSelectedValue() + { + var value = EditorContext.GetLiteralValueOrDefault(); + return _variableTypes.FirstOrDefault(x => x.TypeName == value); + } + + private async Task OnValueChanged(VariableTypeDescriptor? value) + { + await EditorContext.UpdateValueOrLiteralExpressionAsync(value?.TypeName ?? ""); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/VariablePicker.razor b/src/modules/Elsa.Studio.UIHints/Components/VariablePicker.razor new file mode 100644 index 0000000..c47c4f9 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/VariablePicker.razor @@ -0,0 +1,29 @@ +@using Elsa.Api.Client.Shared.UIHints.DropDown +@inject ILocalizer Localizer +@inherits StudioComponentBase + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var selectedValue = GetSelectedValue(); + var searchBox = _items.Count > 10; +} + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/VariablePicker.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/VariablePicker.razor.cs new file mode 100644 index 0000000..fc18393 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/VariablePicker.razor.cs @@ -0,0 +1,70 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.UIHints.DropDown; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; +using System.Text.Json; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// Provides a component for picking a variable. +/// +public partial class VariablePicker +{ + private ICollection _items = Array.Empty(); + + /// + /// Gets or sets the editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = default!; + + private ICollection Variables => EditorContext.WorkflowDefinition.Variables; + + private JsonSerializerOptions JsonSerializerOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + /// + protected override void OnParametersSet() + { + _items = Variables.Select(x => new SelectListItem(x.Name, x.Id)).OrderBy(x => x.Text).ToList(); + } + + private SelectListItem? GetSelectedValue() + { + Variable? value; + if (EditorContext.InputDescriptor.IsWrapped) + { + var expressionValue = EditorContext.GetExpressionValueOrDefault(); + if (string.IsNullOrEmpty(expressionValue)) + value = null; + else + { + try + { + value = JsonSerializer.Deserialize(expressionValue, JsonSerializerOptions); + } + catch (Exception) + { + value = null; + } + } + } + else + value = EditorContext.GetValueOrDefault(); + + return _items.FirstOrDefault(x => x.Value == value?.Id); + } + + private async Task OnValueChanged(SelectListItem? value) + { + var variableId = value?.Value; + var variable = Variables.FirstOrDefault(x => x.Id == variableId); + + if(EditorContext.InputDescriptor.IsWrapped) + await EditorContext.UpdateExpressionAsync(new("Variable", JsonSerializer.Serialize(variable, JsonSerializerOptions))); + else + await EditorContext.UpdateValueAsync(variable); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/WorkflowDefinitionPicker.razor b/src/modules/Elsa.Studio.UIHints/Components/WorkflowDefinitionPicker.razor new file mode 100644 index 0000000..fb7012d --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/WorkflowDefinitionPicker.razor @@ -0,0 +1,31 @@ +@using Elsa.Api.Client.Shared.UIHints.DropDown + +@inherits StudioComponentBase +@inject ILocalizer Localizer + +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var selectedValue = GetSelectedValue(); + var searchBox = _items.Count > 10; +} + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Components/WorkflowDefinitionPicker.razor.cs b/src/modules/Elsa.Studio.UIHints/Components/WorkflowDefinitionPicker.razor.cs new file mode 100644 index 0000000..bcb7eeb --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Components/WorkflowDefinitionPicker.razor.cs @@ -0,0 +1,49 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Api.Client.Shared.Models; +using Elsa.Api.Client.Shared.UIHints.DropDown; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Components; + +/// +/// Provides a component for picking a workflow definition. +/// +public partial class WorkflowDefinitionPicker +{ + private ICollection _items = Array.Empty(); + + /// + /// Gets or sets the editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!; + + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = null!; + + + /// + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + var request = new ListWorkflowDefinitionsRequest(); + var availableWorkflowDefinitions = await WorkflowDefinitionService.ListAsync(request, VersionOptions.Published); + var workflowDefinitions = availableWorkflowDefinitions.Items; + _items = workflowDefinitions.Select(x => new SelectListItem(x.Name, x.DefinitionId)).OrderBy(x => x.Text).ToList(); + + StateHasChanged(); + } + } + + private SelectListItem? GetSelectedValue() + { + var value = EditorContext.GetLiteralValueOrDefault(); + return _items.FirstOrDefault(x => x.Value == value); + } + + private async Task OnValueChanged(SelectListItem? value) + { + await EditorContext.UpdateValueOrLiteralExpressionAsync(value?.Value ?? ""); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Elsa.Studio.UIHints.csproj b/src/modules/Elsa.Studio.UIHints/Elsa.Studio.UIHints.csproj new file mode 100644 index 0000000..6d68262 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Elsa.Studio.UIHints.csproj @@ -0,0 +1,17 @@ + + + + Adds various UI hint handlers for activity input. + elsa studio module + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorCheckListExtensions.cs b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorCheckListExtensions.cs new file mode 100644 index 0000000..302bcc5 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorCheckListExtensions.cs @@ -0,0 +1,31 @@ +using System.Text.Json; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Shared.UIHints.CheckList; + +namespace Elsa.Studio.UIHints.Extensions; + +/// +/// Provides extension methods for . +/// +public static class InputDescriptorCheckListExtensions +{ + /// + /// Gets a list of s for the specified . + /// + public static CheckList GetCheckList(this InputDescriptor descriptor) + { + var specifications = descriptor.UISpecifications; + var props = specifications != null ? specifications.TryGetValue(InputUIHints.CheckList, out var propsValue) ? propsValue is JsonElement value ? value : default : default : default; + + if (props.ValueKind == JsonValueKind.Undefined) + return new([]); + + var serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + var checkListProps = props.Deserialize(serializerOptions); + return checkListProps?.CheckList ?? new CheckList([]); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorCodeEditorExtensions.cs b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorCodeEditorExtensions.cs new file mode 100644 index 0000000..f8e232b --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorCodeEditorExtensions.cs @@ -0,0 +1,30 @@ +using System.Text.Json; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Shared.UIHints.CodeEditor; + +namespace Elsa.Studio.UIHints.Extensions; + +/// +/// Provides extension methods for . +/// +public static class InputDescriptorCodeEditorExtensions +{ + /// + /// Gets the for the specified . + /// + public static CodeEditorOptions GetCodeEditorOptions(this InputDescriptor descriptor) + { + var specifications = descriptor.UISpecifications; + var props = specifications != null ? specifications.TryGetValue(InputUIHints.CodeEditor, out var propsValue) ? propsValue is JsonElement value ? value : default : default : default; + + if (props.ValueKind == JsonValueKind.Undefined) + return new CodeEditorOptions(); + + var serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + return props.Deserialize(serializerOptions)!; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorRadioListExtensions.cs b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorRadioListExtensions.cs new file mode 100644 index 0000000..21d553f --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorRadioListExtensions.cs @@ -0,0 +1,31 @@ +using System.Text.Json; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Shared.UIHints.RadioList; + +namespace Elsa.Studio.UIHints.Extensions; + +/// +/// Provides extension methods for . +/// +public static class InputDescriptorRadioListExtensions +{ + /// + /// Gets a list of s for the specified . + /// + public static RadioList GetRadioList(this InputDescriptor descriptor) + { + var specifications = descriptor.UISpecifications; + var props = specifications != null ? specifications.TryGetValue(InputUIHints.RadioList, out var propsValue) ? propsValue is JsonElement value ? value : default : default : default; + + if (props.ValueKind == JsonValueKind.Undefined) + return new RadioList(Array.Empty()); + + var serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + var radioListProps = props.Deserialize(serializerOptions); + return radioListProps?.RadioList ?? new RadioList(Array.Empty()); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorSelectListExtensions.cs b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorSelectListExtensions.cs new file mode 100644 index 0000000..2117221 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorSelectListExtensions.cs @@ -0,0 +1,31 @@ +using System.Text.Json; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Shared.UIHints.DropDown; + +namespace Elsa.Studio.UIHints.Extensions; + +/// +/// Provides extension methods for . +/// +public static class InputDescriptorSelectListExtensions +{ + /// + /// Gets the for the specified . + /// + public static SelectList GetSelectList(this InputDescriptor descriptor) + { + var specifications = descriptor.UISpecifications; + var props = specifications != null ? specifications.TryGetValue(InputUIHints.DropDown, out var propsValue) ? propsValue is JsonElement value ? value : default : default : default; + + if (props.ValueKind == JsonValueKind.Undefined) + return new([]); + + var serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + var dropDownProps = props.Deserialize(serializerOptions); + return dropDownProps?.SelectList ?? new SelectList([]); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorSingleLineExtensions.cs b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorSingleLineExtensions.cs new file mode 100644 index 0000000..747ddd1 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Extensions/InputDescriptorSingleLineExtensions.cs @@ -0,0 +1,30 @@ +using System.Text.Json; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Shared.UIHints.SingleLine; + +namespace Elsa.Studio.UIHints.Extensions; + +/// +/// Provides extension methods for . +/// +public static class InputDescriptorSingleLineExtensions +{ + /// + /// Gets the for the specified . + /// + public static SingleLineProps GetSingleLineProps(this InputDescriptor descriptor) + { + var specifications = descriptor.UISpecifications; + var props = specifications != null ? specifications.TryGetValue(InputUIHints.SingleLine, out var propsValue) ? propsValue is JsonElement value ? value : default : default : default; + + if (props.ValueKind == JsonValueKind.Undefined) + return new SingleLineProps(); + + var serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + return props.Deserialize(serializerOptions)!; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.UIHints/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..52aeeaa --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,39 @@ +using Elsa.Studio.Extensions; +using Elsa.Studio.UIHints.Handlers; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.UIHints.Extensions; + +/// +/// Provides a set of extension methods for . +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the default UI hint handlers. + /// + public static IServiceCollection AddDefaultUIHintHandlers(this IServiceCollection services) + { + return services + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + .AddUIHintHandler() + ; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Extensions/StringExtensions.cs b/src/modules/Elsa.Studio.UIHints/Extensions/StringExtensions.cs new file mode 100644 index 0000000..9b57c8a --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Extensions/StringExtensions.cs @@ -0,0 +1,23 @@ +namespace Elsa.Studio.UIHints.Extensions; + +/// +/// Provides a set of extension methods for . +/// +public static class StringExtensions +{ + /// + /// Trims the whitespace from the string, including null characters and new lines. + /// + public static string TrimWhitespace(this string value) + { + return value.Trim(' ', '\0', '\n', '\r'); + } + + /// + /// Trims the null characters from the string. + /// + public static string TrimNull(this string value) + { + return value.Trim('\0'); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/FodyWeavers.xml b/src/modules/Elsa.Studio.UIHints/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/FodyWeavers.xsd b/src/modules/Elsa.Studio.UIHints/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/CheckListHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/CheckListHandler.cs new file mode 100644 index 0000000..c0f2087 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/CheckListHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class CheckListHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.CheckList; + + /// + public string UISyntax => WellKnownSyntaxNames.Object; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(CheckList)); + builder.AddAttribute(1, nameof(CheckList.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/CheckboxHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/CheckboxHandler.cs new file mode 100644 index 0000000..7b76257 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/CheckboxHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class CheckboxHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.Checkbox; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(Checkbox)); + builder.AddAttribute(1, nameof(Checkbox.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/CodeEditorHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/CodeEditorHandler.cs new file mode 100644 index 0000000..51d6d01 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/CodeEditorHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class CodeEditorHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.CodeEditor; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(Code)); + builder.AddAttribute(1, nameof(Code.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/DateTimePickerHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/DateTimePickerHandler.cs new file mode 100644 index 0000000..c6be3d5 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/DateTimePickerHandler.cs @@ -0,0 +1,23 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +public class DateTimePickerHandler : IUIHintHandler +{ + public bool GetSupportsUIHint(string uiHint) => uiHint == InputUIHints.DateTimePicker; + + public string UISyntax => WellKnownSyntaxNames.Literal; + + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(DateTimePicker)); + builder.AddAttribute(1, nameof(DateTimePicker.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/DropDownHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/DropDownHandler.cs new file mode 100644 index 0000000..442fa41 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/DropDownHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class DropDownHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.DropDown; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(Dropdown)); + builder.AddAttribute(1, nameof(Dropdown.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/DynamicOutcomesHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/DynamicOutcomesHandler.cs new file mode 100644 index 0000000..c32b2b1 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/DynamicOutcomesHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class DynamicOutcomesHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.DynamicOutcomes; + + /// + public string UISyntax => WellKnownSyntaxNames.Object; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(DynamicOutcomes)); + builder.AddAttribute(1, nameof(DynamicOutcomes.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/ExpressionEditorHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/ExpressionEditorHandler.cs new file mode 100644 index 0000000..e3fb8fb --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/ExpressionEditorHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class ExpressionEditorHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.ExpressionEditor; + + /// + public string UISyntax => "JavaScript"; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(ExpressionEditor)); + builder.AddAttribute(1, nameof(ExpressionEditor.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/HttpStatusCodesHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/HttpStatusCodesHandler.cs new file mode 100644 index 0000000..471b829 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/HttpStatusCodesHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class HttpStatusCodesHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.HttpStatusCodes; + + /// + public string UISyntax => WellKnownSyntaxNames.Object; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(HttpStatusCodes)); + builder.AddAttribute(1, nameof(HttpStatusCodes.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/JsonEditorHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/JsonEditorHandler.cs new file mode 100644 index 0000000..cf1e42b --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/JsonEditorHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class JsonEditorHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.JsonEditor; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(Json)); + builder.AddAttribute(1, nameof(Json.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/MultiLineHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/MultiLineHandler.cs new file mode 100644 index 0000000..6e1f68c --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/MultiLineHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class MultiLineHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.MultiLine; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(MultiLine)); + builder.AddAttribute(1, nameof(MultiLine.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/MultiTextHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/MultiTextHandler.cs new file mode 100644 index 0000000..4cb0a9d --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/MultiTextHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class MultiTextHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.MultiText; + + /// + public string UISyntax => WellKnownSyntaxNames.Object; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(MultiText)); + builder.AddAttribute(1, nameof(MultiText.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/OutcomePickerHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/OutcomePickerHandler.cs new file mode 100644 index 0000000..d35aee8 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/OutcomePickerHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class OutcomePickerHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.OutcomePicker; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(OutcomePicker)); + builder.AddAttribute(1, nameof(OutcomePicker.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/OutputPickerHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/OutputPickerHandler.cs new file mode 100644 index 0000000..03697b0 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/OutputPickerHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class OutputPickerHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.OutputPicker; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(OutputPicker)); + builder.AddAttribute(1, nameof(OutputPicker.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/RadioListHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/RadioListHandler.cs new file mode 100644 index 0000000..872c597 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/RadioListHandler.cs @@ -0,0 +1,23 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +public class RadioListHandler : IUIHintHandler +{ + public bool GetSupportsUIHint(string uiHint) => uiHint == InputUIHints.RadioList; + + public string UISyntax => WellKnownSyntaxNames.Literal; + + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(RadioList)); + builder.AddAttribute(1, nameof(RadioList.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/SingleLineHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/SingleLineHandler.cs new file mode 100644 index 0000000..8d39542 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/SingleLineHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class SingleLineHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint == InputUIHints.SingleLine; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(SingleLine)); + builder.AddAttribute(1, nameof(SingleLine.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/SwitchEditorHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/SwitchEditorHandler.cs new file mode 100644 index 0000000..92a4ab4 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/SwitchEditorHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the and UI hints. +/// +public class SwitchEditorHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.FlowSwitchEditor or InputUIHints.SwitchEditor; + + /// + public string UISyntax => WellKnownSyntaxNames.Object; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(Cases)); + builder.AddAttribute(1, nameof(Cases.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/TypePickerHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/TypePickerHandler.cs new file mode 100644 index 0000000..f40b3ed --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/TypePickerHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class TypePickerHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.TypePicker; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(TypePicker)); + builder.AddAttribute(1, nameof(TypePicker.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/VariablePickerHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/VariablePickerHandler.cs new file mode 100644 index 0000000..4140c09 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/VariablePickerHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class VariablePickerHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.VariablePicker; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(VariablePicker)); + builder.AddAttribute(1, nameof(VariablePicker.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Handlers/WorkflowDefinitionPickerHandler.cs b/src/modules/Elsa.Studio.UIHints/Handlers/WorkflowDefinitionPickerHandler.cs new file mode 100644 index 0000000..6094224 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Handlers/WorkflowDefinitionPickerHandler.cs @@ -0,0 +1,29 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.UIHints.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.UIHints.Handlers; + +/// +/// Provides a handler for the UI hint. +/// +public class WorkflowDefinitionPickerHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint is InputUIHints.WorkflowDefinitionPicker; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(WorkflowDefinitionPicker)); + builder.AddAttribute(1, nameof(WorkflowDefinitionPicker.EditorContext), context); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/Helpers/JsonParser.cs b/src/modules/Elsa.Studio.UIHints/Helpers/JsonParser.cs new file mode 100644 index 0000000..7f87753 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/Helpers/JsonParser.cs @@ -0,0 +1,34 @@ +using System.Text.Json; + +namespace Elsa.Studio.UIHints.Helpers; + +public static class JsonParser +{ + /// + /// Parses the specified JSON string into an object of type . + /// + /// The JSON string to parse. + /// A factory function that returns a default value of type . + /// The to use when parsing the JSON string. + /// The type of the object to parse the JSON string into. + /// An object of type . + public static T ParseJson(string? json, Func defaultValueFactory, JsonSerializerOptions? options = default) + { + if (string.IsNullOrWhiteSpace(json)) + return defaultValueFactory(); + + try + { + options ??= new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + return JsonSerializer.Deserialize(json, options) ?? defaultValueFactory(); + } + catch (JsonException) + { + return defaultValueFactory(); + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/InputUIHints.cs b/src/modules/Elsa.Studio.UIHints/InputUIHints.cs new file mode 100644 index 0000000..c2c6e93 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/InputUIHints.cs @@ -0,0 +1,28 @@ +namespace Elsa.Studio.UIHints; + +/// +/// Provides a set of well-known UI hints. +/// +public static class InputUIHints +{ + public const string Checkbox = "checkbox"; + public const string CheckList = "checklist"; + public const string CodeEditor = "code-editor"; + public const string DateTimePicker = "datetime-picker"; + public const string DropDown = "dropdown"; + public const string DynamicOutcomes = "dynamic-outcomes"; + public const string ExpressionEditor = "expression-editor"; + public const string HttpStatusCodes = "http-status-codes"; + public const string JsonEditor = "json-editor"; + public const string MultiLine = "multiline"; + public const string MultiText = "multitext"; + public const string OutcomePicker = "outcome-picker"; + public const string OutputPicker = "output-picker"; + public const string RadioList = "radiolist"; + public const string SingleLine = "singleline"; + public const string FlowSwitchEditor = "flow-switch-editor"; + public const string SwitchEditor = "switch-editor"; + public const string TypePicker = "type-picker"; + public const string VariablePicker = "variable-picker"; + public const string WorkflowDefinitionPicker = "workflow-definition-picker"; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.UIHints/_Imports.razor b/src/modules/Elsa.Studio.UIHints/_Imports.razor new file mode 100644 index 0000000..1f6d130 --- /dev/null +++ b/src/modules/Elsa.Studio.UIHints/_Imports.razor @@ -0,0 +1,5 @@ +@using Microsoft.AspNetCore.Components.Web +@using Elsa.Studio.Components +@using Elsa.Studio.Localization +@using MudBlazor +@using MudExtensions \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Webhooks/Elsa.Studio.Webhooks.csproj b/src/modules/Elsa.Studio.Webhooks/Elsa.Studio.Webhooks.csproj new file mode 100644 index 0000000..946d033 --- /dev/null +++ b/src/modules/Elsa.Studio.Webhooks/Elsa.Studio.Webhooks.csproj @@ -0,0 +1,17 @@ + + + + Adds webhook management to the studio. + elsa studio module + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Webhooks/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Webhooks/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..eb3d509 --- /dev/null +++ b/src/modules/Elsa.Studio.Webhooks/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,15 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Webhooks.Menu; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Webhooks.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddWebhooksModule(this IServiceCollection services) + { + return services + .AddScoped() + .AddScoped(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Webhooks/FodyWeavers.xml b/src/modules/Elsa.Studio.Webhooks/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Webhooks/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Webhooks/FodyWeavers.xsd b/src/modules/Elsa.Studio.Webhooks/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Webhooks/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Webhooks/Menu/WebhooksMenu.cs b/src/modules/Elsa.Studio.Webhooks/Menu/WebhooksMenu.cs new file mode 100644 index 0000000..2b4ec9d --- /dev/null +++ b/src/modules/Elsa.Studio.Webhooks/Menu/WebhooksMenu.cs @@ -0,0 +1,26 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Services; +using MudBlazor; + +namespace Elsa.Studio.Webhooks.Menu; + +public class WebhooksMenu(ILocalizer localizer) : IMenuProvider +{ + public ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default) + { + var menuItems = new List + { + new() + { + Icon = Icons.Material.Filled.Http, + Href = "webhooks", + Text = localizer["Webhooks"], + GroupName = MenuItemGroups.Settings.Name + } + }; + + return new ValueTask>(menuItems); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Webhooks/Module.cs b/src/modules/Elsa.Studio.Webhooks/Module.cs new file mode 100644 index 0000000..875310f --- /dev/null +++ b/src/modules/Elsa.Studio.Webhooks/Module.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Abstractions; + +namespace Elsa.Studio.Webhooks; + +public class Feature : FeatureBase +{ + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Webhooks/Pages/Index.razor b/src/modules/Elsa.Studio.Webhooks/Pages/Index.razor new file mode 100644 index 0000000..777fdf1 --- /dev/null +++ b/src/modules/Elsa.Studio.Webhooks/Pages/Index.razor @@ -0,0 +1,8 @@ +@page "/webhooks" +@inherits StudioComponentBase + +Webhooks + + + + diff --git a/src/modules/Elsa.Studio.Webhooks/_Imports.razor b/src/modules/Elsa.Studio.Webhooks/_Imports.razor new file mode 100644 index 0000000..93919a4 --- /dev/null +++ b/src/modules/Elsa.Studio.Webhooks/_Imports.razor @@ -0,0 +1,7 @@ +@using Elsa.Studio.Components +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.JSInterop +@using MudBlazor +@attribute [Authorize] \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/ActivityTabs/WorkflowContextActivityTab.cs b/src/modules/Elsa.Studio.WorkflowContexts/ActivityTabs/WorkflowContextActivityTab.cs new file mode 100644 index 0000000..0314352 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/ActivityTabs/WorkflowContextActivityTab.cs @@ -0,0 +1,28 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.WorkflowContexts.Components; +using Microsoft.AspNetCore.Components; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Elsa.Studio.WorkflowContexts.ActivityTabs +{ + public class WorkflowContextActivityTab(ILocalizer localizer) : IActivityTab + { + public string Title => localizer["Workflow Context"]; + + public Func, RenderFragment> Render => attributes => builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, nameof(WorkflowContextActivityTabPanel.WorkflowDefinition), attributes["WorkflowDefinition"]); + builder.AddAttribute(2, nameof(WorkflowContextActivityTabPanel.Activity), attributes["Activity"]); + builder.AddAttribute(2, nameof(WorkflowContextActivityTabPanel.ActivityDescriptor), attributes["ActivityDescriptor"]); + builder.AddAttribute(2, nameof(WorkflowContextActivityTabPanel.OnActivityUpdated), attributes["OnActivityUpdated"]); + builder.CloseComponent(); + }; + + } +} diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextActivityTabPanel.razor b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextActivityTabPanel.razor new file mode 100644 index 0000000..6cc8c0e --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextActivityTabPanel.razor @@ -0,0 +1,35 @@ +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +
+ + + @Localizer["Workflow Context Settings"] + @if (_items.Count > 0) + { + + + @foreach (var item in _items) + { + + + @Localizer[@item.Text] + + + + + + + + + } + + + + } + + + +
+ diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextActivityTabPanel.razor.cs b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextActivityTabPanel.razor.cs new file mode 100644 index 0000000..4d4311b --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextActivityTabPanel.razor.cs @@ -0,0 +1,125 @@ +namespace Elsa.Studio.WorkflowContexts.Components; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; + +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowExecutionContexts.Models; +using Elsa.Api.Client.Shared.UIHints.DropDown; +using Elsa.Extensions; +using Elsa.Studio.WorkflowContexts.Contracts; +using Elsa.Studio.WorkflowContexts.Extensions; +using Elsa.Studio.WorkflowContexts.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using System.Diagnostics; +using System.Text.Json.Nodes; + +public partial class WorkflowContextActivityTabPanel +{ + /// + /// Gets or sets the workflow definition. + /// + [Parameter] + public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// + /// Gets or sets the activity. + /// + [Parameter] + public JsonObject? Activity { get; set; } + + /// + /// Gets or sets the activity descriptor. + /// + [Parameter] + public ActivityDescriptor? ActivityDescriptor { get; set; } + + /// + /// Gets or sets a callback that is invoked when the activity is updated. + /// + [Parameter] + public Func? OnActivityUpdated { get; set; } + + [Inject] private IWorkflowContextsProvider WorkflowContextsProvider { get; set; } = default!; + + [CascadingParameter] private IWorkspace? Workspace { get; set; } + + private bool IsReadOnly => Workspace?.IsReadOnly == true; + + private ICollection _items = Array.Empty(); + + private Dictionary _contextSettings = new Dictionary(); + + private ICollection WorkflowContextDescriptors { get; set; } = new List(); + + /// + protected override async Task OnInitializedAsync() + { + WorkflowContextDescriptors = (await WorkflowContextsProvider.ListAsync()).ToList(); + } + + protected override void OnParametersSet() + { + var selectedContextProviders = WorkflowDefinition!.GetWorkflowContextProviderTypes(); + _items = WorkflowContextDescriptors.Where(descriptior => selectedContextProviders.Contains(descriptior.Type)) + .Select(descriptior => new SelectListItem(descriptior.Name, descriptior.Type)).ToList(); + + + if (Activity != null) + { + _contextSettings = Activity.GetWorkflowContextSettings() ?? new Dictionary(); + } + } + + + private bool IsChecked(string type, string function) + { + try + { + if (_contextSettings.ContainsKey(type)) + { + return function switch + { + "Load" => _contextSettings[type].Load, + "Save" => _contextSettings[type].Save, + _ => false + }; + + } + } + catch + { + + } + return false; + } + + private async Task OnValueChanged(string type, string function, bool? value) + { + if (Activity != null) + { + if (value.HasValue) + { + if (!_contextSettings.ContainsKey(type)) + { + _contextSettings[type] = new ActivityWorkflowContextSettings(); + } + + if (String.Equals(function, "Load", StringComparison.OrdinalIgnoreCase)) + { + _contextSettings[type].Load = value.Value; + } + if (String.Equals(function, "Save", StringComparison.OrdinalIgnoreCase)) + { + _contextSettings[type].Save = value.Value; + } + } + + Activity.SetWorkflowContextSettings(_contextSettings); + + + if (OnActivityUpdated != null) + await OnActivityUpdated(Activity); + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextProviderPicker.razor b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextProviderPicker.razor new file mode 100644 index 0000000..cec107e --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextProviderPicker.razor @@ -0,0 +1,24 @@ +@using Elsa.Api.Client.Shared.UIHints.DropDown +@inherits StudioComponentBase +@{ + var inputDescriptor = EditorContext.InputDescriptor; + var displayName = inputDescriptor.DisplayName; + var description = inputDescriptor.Description; + var selectedValue = GetSelectedValue(); + var searchBox = _items.Count > 10; +} + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextProviderPicker.razor.cs b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextProviderPicker.razor.cs new file mode 100644 index 0000000..ec7654d --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextProviderPicker.razor.cs @@ -0,0 +1,52 @@ +using Elsa.Api.Client.Shared.UIHints.DropDown; +using Elsa.Api.Client.Resources.WorkflowExecutionContexts.Models; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; +using Elsa.Extensions; +using Elsa.Studio.WorkflowContexts.Contracts; +using Elsa.Api.Client.Resources.Scripting.Models; + +namespace Elsa.Studio.WorkflowContexts.Components; + +/// +/// A component that renders the workflow context drop down. +/// +public partial class WorkflowContextProviderPicker +{ + private ICollection _items = Array.Empty(); + + /// + /// Gets or sets the editor context. + /// + [Parameter] public DisplayInputEditorContext EditorContext { get; set; } = default!; + + [Inject] private IWorkflowContextsProvider WorkflowContextsProvider { get; set; } = default!; + + private ICollection WorkflowContextDescriptors { get; set; } = new List(); + + /// + protected override async Task OnInitializedAsync() + { + WorkflowContextDescriptors = (await WorkflowContextsProvider.ListAsync()).ToList(); + } + + /// + protected override void OnParametersSet() + { + var selectedContextProviders = EditorContext.WorkflowDefinition.GetWorkflowContextProviderTypes(); + _items = WorkflowContextDescriptors.Where(descriptior => selectedContextProviders.Contains(descriptior.Type)) + .Select(descriptior => new SelectListItem(descriptior.Name, descriptior.Type)).ToList(); + } + + private SelectListItem? GetSelectedValue() + { + var value = EditorContext.GetLiteralValueOrDefault(); + return _items.FirstOrDefault(x => x.Value == value); + } + + private async Task OnValueChanged(SelectListItem? value) + { + var expression = Expression.CreateLiteral(value?.Value ?? ""); + await EditorContext.UpdateExpressionAsync(expression); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextsEditor.razor b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextsEditor.razor new file mode 100644 index 0000000..7633ac7 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextsEditor.razor @@ -0,0 +1,13 @@ +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +@Localizer["Workflow Context"] + + + @foreach (var descriptor in WorkflowContextDescriptors) + { + + } + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextsEditor.razor.cs b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextsEditor.razor.cs new file mode 100644 index 0000000..12aab79 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Components/WorkflowContextsEditor.razor.cs @@ -0,0 +1,55 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowExecutionContexts.Models; +using Elsa.Extensions; +using Elsa.Studio.WorkflowContexts.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.WorkflowContexts.Components; + +/// +/// A component that renders the workflow context editor. +/// +public partial class WorkflowContextsEditor +{ + /// + /// Gets or sets the workflow definition. + /// + [Parameter] + public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + + /// + /// Gets or sets the callback that is invoked when the workflow definition is updated. + /// + [Parameter] + public EventCallback WorkflowDefinitionUpdated { get; set; } + + [Inject] private IWorkflowContextsProvider WorkflowContextsProvider { get; set; } = default!; + + private ICollection WorkflowContextDescriptors { get; set; } = new List(); + private ISet SelectedWorkflowContextTypes { get; set; } = new HashSet(); + + /// + protected override async Task OnInitializedAsync() + { + WorkflowContextDescriptors = (await WorkflowContextsProvider.ListAsync()).ToList(); + } + + /// + protected override void OnParametersSet() + { + SelectedWorkflowContextTypes = WorkflowDefinition.GetWorkflowContextProviderTypes().ToHashSet(); + } + + private async Task OnCheckChanged(WorkflowContextProviderDescriptor descriptor, bool isChecked) + { + if (isChecked) + SelectedWorkflowContextTypes.Add(descriptor.Type); + else + SelectedWorkflowContextTypes.Remove(descriptor.Type); + + WorkflowDefinition.SetWorkflowContextProviderTypes(SelectedWorkflowContextTypes); + + if (WorkflowDefinitionUpdated.HasDelegate) + await WorkflowDefinitionUpdated.InvokeAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Contracts/IWorkflowContextsProvider.cs b/src/modules/Elsa.Studio.WorkflowContexts/Contracts/IWorkflowContextsProvider.cs new file mode 100644 index 0000000..2d3789d --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Contracts/IWorkflowContextsProvider.cs @@ -0,0 +1,14 @@ +using Elsa.Api.Client.Resources.WorkflowExecutionContexts.Models; + +namespace Elsa.Studio.WorkflowContexts.Contracts; + +/// +/// Provides workflow contexts. +/// +public interface IWorkflowContextsProvider +{ + /// + /// Returns a list of workflow context provider descriptors. + /// + Task> ListAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Elsa.Studio.WorkflowContexts.csproj b/src/modules/Elsa.Studio.WorkflowContexts/Elsa.Studio.WorkflowContexts.csproj new file mode 100644 index 0000000..2a17ad9 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Elsa.Studio.WorkflowContexts.csproj @@ -0,0 +1,14 @@ + + + + Enables Workflow Context management + elsa studio module + + + + + + + + + diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Extensions/ActivityExtensions.cs b/src/modules/Elsa.Studio.WorkflowContexts/Extensions/ActivityExtensions.cs new file mode 100644 index 0000000..9ff0307 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Extensions/ActivityExtensions.cs @@ -0,0 +1,20 @@ +using Elsa.Api.Client.Extensions; +using Elsa.Studio.WorkflowContexts.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Nodes; +using System.Threading.Tasks; + +namespace Elsa.Studio.WorkflowContexts.Extensions +{ + public static class ActivityExtensions + { + public static void SetWorkflowContextSettings(this JsonObject activity, Dictionary value) => + activity.SetProperty(JsonValue.Create(value), "customProperties", "ActivityWorkflowContextSettingsKey"); + + public static Dictionary GetWorkflowContextSettings(this JsonObject activity) => + activity.GetProperty>("customProperties", "ActivityWorkflowContextSettingsKey"); + } +} diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.WorkflowContexts/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..db0d73a --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,28 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.WorkflowContexts.Contracts; +using Elsa.Studio.WorkflowContexts.Handlers; +using Elsa.Studio.WorkflowContexts.Services; +using Elsa.Studio.Extensions; +using Microsoft.Extensions.DependencyInjection; +using Elsa.Studio.WorkflowContexts.ActivityTabs; + +namespace Elsa.Studio.WorkflowContexts.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the workflow vcontexts module to the service collection. + /// + public static IServiceCollection AddWorkflowContextsModule(this IServiceCollection services) + { + return services + .AddScoped() + .AddScoped() + .AddUIHintHandler() + .AddScoped() + ; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Extensions/WorkflowDefinitionExtensions.cs b/src/modules/Elsa.Studio.WorkflowContexts/Extensions/WorkflowDefinitionExtensions.cs new file mode 100644 index 0000000..cae509d --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Extensions/WorkflowDefinitionExtensions.cs @@ -0,0 +1,39 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; + +// ReSharper disable once CheckNamespace +namespace Elsa.Extensions; + +/// +/// Adds extension methods to . +/// +public static class WorkflowDefinitionExtensions +{ + /// + /// Gets the workflow context provider types that are installed on the workflow definition. + /// + /// The workflow definition to get the provider types from. + /// The workflow context provider types. + public static IEnumerable GetWorkflowContextProviderTypes(this WorkflowDefinition workflowDefinition) + { + if (!workflowDefinition.CustomProperties.TryGetValue("Elsa:WorkflowContextProviderTypes", out var providerTypesValue)) + return []; + + var jsonElement = (JsonElement)providerTypesValue; + return jsonElement.Deserialize(JsonSerializerOptions.Default); + } + + /// + /// Gets the workflow context provider types that are installed on the workflow definition. + /// + /// The workflow definition to get the provider types from. + /// The workflow context provider types. + /// The workflow context provider types. + public static void SetWorkflowContextProviderTypes(this WorkflowDefinition workflowDefinition, IEnumerable value) + { + var jsonElement = JsonSerializer.SerializeToElement(value.ToArray()); + workflowDefinition.CustomProperties["Elsa:WorkflowContextProviderTypes"] = jsonElement; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Feature.cs b/src/modules/Elsa.Studio.WorkflowContexts/Feature.cs new file mode 100644 index 0000000..257f64b --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Feature.cs @@ -0,0 +1,28 @@ +using Elsa.Studio.Abstractions; +using Elsa.Studio.Attributes; +using Elsa.Studio.Contracts; +using Elsa.Studio.WorkflowContexts.Widgets; + +namespace Elsa.Studio.WorkflowContexts; + +/// +/// Registers the workflow contexts feature. +/// +[RemoteFeature("Elsa.WorkflowContexts")] +public class Feature : FeatureBase +{ + private readonly IWidgetRegistry _widgetRegistry; + + /// + public Feature(IWidgetRegistry widgetRegistry) + { + _widgetRegistry = widgetRegistry; + } + + /// + public override ValueTask InitializeAsync(CancellationToken cancellationToken = default) + { + _widgetRegistry.Add(new WorkflowContextsEditorWidget()); + return default; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/FodyWeavers.xml b/src/modules/Elsa.Studio.WorkflowContexts/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/FodyWeavers.xsd b/src/modules/Elsa.Studio.WorkflowContexts/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Handlers/WorkflowContextProviderPickerHandler.cs b/src/modules/Elsa.Studio.WorkflowContexts/Handlers/WorkflowContextProviderPickerHandler.cs new file mode 100644 index 0000000..41d73f8 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Handlers/WorkflowContextProviderPickerHandler.cs @@ -0,0 +1,26 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; +using Elsa.Studio.WorkflowContexts.Components; + +namespace Elsa.Studio.WorkflowContexts.Handlers; + +public class WorkflowContextProviderPickerHandler : IUIHintHandler +{ + /// + public bool GetSupportsUIHint(string uiHint) => uiHint == "workflow-context-provider-picker"; + + /// + public string UISyntax => WellKnownSyntaxNames.Literal; + + /// + public RenderFragment DisplayInputEditor(DisplayInputEditorContext context) + { + return builder => + { + builder.OpenComponent(0, typeof(WorkflowContextProviderPicker)); + builder.AddAttribute(1, nameof(WorkflowContextProviderPicker.EditorContext), context); + builder.CloseComponent(); + }; + } +} diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Models/ActivityWorkflowContextSettings.cs b/src/modules/Elsa.Studio.WorkflowContexts/Models/ActivityWorkflowContextSettings.cs new file mode 100644 index 0000000..29f24e0 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Models/ActivityWorkflowContextSettings.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Elsa.Studio.WorkflowContexts.Models; + +public class ActivityWorkflowContextSettings +{ + /// + /// Whether to load the context before executing the activity. + /// + public bool Load { get; set; } + + /// + /// Whether to save the context after executing the activity. + /// + public bool Save { get; set; } +} diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Services/RemoteWorkflowContextsProvider.cs b/src/modules/Elsa.Studio.WorkflowContexts/Services/RemoteWorkflowContextsProvider.cs new file mode 100644 index 0000000..72fe3b9 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Services/RemoteWorkflowContextsProvider.cs @@ -0,0 +1,30 @@ +using Elsa.Api.Client.Resources.WorkflowExecutionContexts.Contracts; +using Elsa.Api.Client.Resources.WorkflowExecutionContexts.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.WorkflowContexts.Contracts; + +namespace Elsa.Studio.WorkflowContexts.Services; + +/// +/// Provides workflow contexts from a remote API. +/// +public class RemoteWorkflowContextsProvider : IWorkflowContextsProvider +{ + private readonly IBackendApiClientProvider _backendApiClientProvider; + + /// + /// Initializes a new instance of the class. + /// + public RemoteWorkflowContextsProvider(IBackendApiClientProvider backendApiClientProvider) + { + _backendApiClientProvider = backendApiClientProvider; + } + + /// + public async Task> ListAsync(CancellationToken cancellationToken = default) + { + var api = await _backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(cancellationToken); + return response.Items; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/Widgets/WorkflowContextsEditorWidget.cs b/src/modules/Elsa.Studio.WorkflowContexts/Widgets/WorkflowContextsEditorWidget.cs new file mode 100644 index 0000000..c6e7c56 --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/Widgets/WorkflowContextsEditorWidget.cs @@ -0,0 +1,27 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.WorkflowContexts.Components; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.WorkflowContexts.Widgets; + +/// +/// A widget that renders the workflow context editor. +/// +public class WorkflowContextsEditorWidget : IWidget +{ + /// + public string Zone => "workflow-definition-properties"; + + /// + public double Order => 25; + + /// + public Func, RenderFragment> Render => attributes => builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, nameof(WorkflowContextsEditor.WorkflowDefinition), attributes["WorkflowDefinition"]); + builder.AddAttribute(2, nameof(WorkflowContextsEditor.WorkflowDefinitionUpdated), attributes["WorkflowDefinitionUpdated"]); + builder.CloseComponent(); + + }; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.WorkflowContexts/_Imports.razor b/src/modules/Elsa.Studio.WorkflowContexts/_Imports.razor new file mode 100644 index 0000000..5c4672b --- /dev/null +++ b/src/modules/Elsa.Studio.WorkflowContexts/_Imports.razor @@ -0,0 +1,15 @@ +@using System.ComponentModel.DataAnnotations +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.AspNetCore.Components.Forms +@using Blazored.FluentValidation +@using Elsa.Studio.Components +@using Elsa.Studio.Localization +@using Humanizer +@using MudBlazor +@using MudExtensions +@using Radzen +@using Radzen.Blazor + +@attribute [Authorize] \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contexts/PortProviderContext.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contexts/PortProviderContext.cs new file mode 100644 index 0000000..89218c6 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contexts/PortProviderContext.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; + +namespace Elsa.Studio.Workflows.Domain.Contexts; + +/// +/// Represents the context for a port provider. +/// +/// The descriptor of te activity for which ports are being provided. +/// The activity for which ports are being provided. +public record PortProviderContext(ActivityDescriptor ActivityDescriptor, JsonObject Activity); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/CompatWorkflowJsonDetector.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/CompatWorkflowJsonDetector.cs new file mode 100644 index 0000000..d868335 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/CompatWorkflowJsonDetector.cs @@ -0,0 +1,22 @@ +using Elsa.Studio.Workflows.Domain.Services; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A service that detects whether a JSON string is a workflow definition, +/// first using a schema, then using a simple heuristic. +/// +public class CompatWorkflowJsonDetector : IWorkflowJsonDetector +{ + /// + public bool IsWorkflowSchema(string json) + { + var schemaDetector = new SchemaWorkflowJsonDetector(); + + if (schemaDetector.IsWorkflowSchema(json)) + return true; + + var simpleDetector = new SimpleWorkflowJsonDetector(); + return simpleDetector.IsWorkflowSchema(json); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityExecutionService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityExecutionService.cs new file mode 100644 index 0000000..032acdf --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityExecutionService.cs @@ -0,0 +1,37 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.ActivityExecutions.Models; +using Elsa.Api.Client.Resources.Resilience.Models; +using Elsa.Api.Client.Shared.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A service that provides information about the execution of activities. +/// +public interface IActivityExecutionService +{ + /// + /// Gets a report of the execution of activities. + /// + Task GetReportAsync(string workflowInstanceId, JsonObject containerActivity, CancellationToken cancellationToken = default); + + /// + /// Gets a list of activity execution records. + /// + Task> ListAsync(string workflowInstanceId, string activityNodeId, CancellationToken cancellationToken = default); + + /// + /// Gets a list of activity execution record summaries. + /// + Task> ListSummariesAsync(string workflowInstanceId, string activityNodeId, CancellationToken cancellationToken = default); + + /// + /// Gets an individual activity execution record. + /// + Task GetAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Retrieves a paginated list of retry attempt records for a specific activity instance. + /// + Task> GetRetriesAsync(string activityInstanceId, int? skip = null, int? take = null, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityIdGenerator.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityIdGenerator.cs new file mode 100644 index 0000000..b396844 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityIdGenerator.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Generates unique activity IDs. +/// +public interface IIdentityGenerator +{ + /// + /// Generates a unique activity ID. + /// + string GenerateId(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityNameGenerator.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityNameGenerator.cs new file mode 100644 index 0000000..1ddab48 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityNameGenerator.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Generates unique activity names. +/// +public interface IActivityNameGenerator +{ + /// + /// Returns true if the specified name already exists in the container. + /// + bool GetNameExists(IEnumerable activities, string name); + + /// + /// Generates a unique name for the specified activity descriptor. + /// + string GenerateNextName(IEnumerable activities, ActivityDescriptor activityDescriptor); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityPortProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityPortProvider.cs new file mode 100644 index 0000000..f6cab98 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityPortProvider.cs @@ -0,0 +1,49 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contexts; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Provides ports for activities. +/// +public interface IActivityPortProvider +{ + /// + /// Gets the priority of the provider. + /// + double Priority { get; } + + /// + /// Returns true if the provider supports the specified activity type. + /// + bool GetSupportsActivityType(PortProviderContext context); + + /// + /// Returns the ports for the specified activity. + /// + /// The context. + IEnumerable GetPorts(PortProviderContext context); + + /// + /// Returns the activity for the specified port. + /// + /// The name of the port. + /// The context. + JsonObject? ResolvePort(string portName, PortProviderContext context); + + /// + /// Assigns the specified activity to the specified port. + /// + /// The name of the port. + /// The activity to assign. + /// The context. + void AssignPort(string portName, JsonObject activity, PortProviderContext context); + + /// + /// Clears the specified port. + /// + /// The name of the port. + /// The context. + void ClearPort(string portName, PortProviderContext context); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityPortService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityPortService.cs new file mode 100644 index 0000000..06da803 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityPortService.cs @@ -0,0 +1,10 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contexts; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +public interface IActivityPortService +{ + IActivityPortProvider GetProvider(PortProviderContext context); + IEnumerable GetPorts(PortProviderContext context); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityRegistry.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityRegistry.cs new file mode 100644 index 0000000..7496e09 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityRegistry.cs @@ -0,0 +1,45 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Represents a registry of activity descriptors. +/// +public interface IActivityRegistry +{ + /// + /// Refreshes the list of activity descriptors. + /// + Task RefreshAsync(CancellationToken cancellationToken = default); + + /// + /// Ensures that the list of activity descriptors is loaded. + /// + Task EnsureLoadedAsync(CancellationToken cancellationToken = default); + + /// + /// Returns a list of the latest versions of activity descriptors. + /// + /// A list of activity descriptors. + IEnumerable List(); + + /// + /// Finds an activity descriptor by its type. + /// + /// The activity type. + /// The activity version. + /// The activity descriptor. + ActivityDescriptor? Find(string activityType, int? version = default); + + /// + /// Finds all activity descriptor versions by type. + /// + /// + /// + IEnumerable FindAll(string activityType); + + /// + /// Marks the activity registry as stale. + /// + void MarkStale(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityRegistryProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityRegistryProvider.cs new file mode 100644 index 0000000..143bec4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityRegistryProvider.cs @@ -0,0 +1,14 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Provides a list of activity descriptors to the activity registry. This is a way to abstract the source of activity descriptors. +/// +public interface IActivityRegistryProvider +{ + /// + /// Returns a list of activity descriptors. + /// + Task> ListAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityResolver.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityResolver.cs new file mode 100644 index 0000000..2a490e1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityResolver.cs @@ -0,0 +1,29 @@ +using System.Text.Json.Nodes; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// An activity resolver inspects a given activity and returns its contained activities. +/// Node resolvers are used to inspect a workflow structure and build a graph of nodes from it for easy node traversal. +/// +public interface IActivityResolver +{ + /// + /// The priority of this resolver. Resolvers with higher priority are executed first. + /// + int Priority { get; } + + /// + /// Returns true if this resolver supports the specified activity. + /// + bool GetSupportsActivity(JsonObject activity); + + /// + /// Returns a list of contained activities for the specified activity. + /// + /// + /// + /// + ValueTask> GetActivitiesAsync(JsonObject activity, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityVisitor.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityVisitor.cs new file mode 100644 index 0000000..f9172b0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IActivityVisitor.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Shared.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Represents a visitor that can visit an activity. +/// +public interface IActivityVisitor +{ + /// + /// Visits the specified activity and returns a graph of activities. + /// + /// + /// + /// + Task VisitAsync(JsonObject activity, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/ICommitStrategiesProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/ICommitStrategiesProvider.cs new file mode 100644 index 0000000..5cd0bbf --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/ICommitStrategiesProvider.cs @@ -0,0 +1,19 @@ +using Elsa.Api.Client.Resources.CommitStrategies.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Provides commit strategies for workflows and activities. +/// +public interface ICommitStrategiesProvider +{ + /// + /// Gets workflow commit strategies. + /// + ValueTask> GetWorkflowCommitStrategiesAsync(CancellationToken cancellationToken = default); + + /// + /// Gets activity commit strategies. + /// + ValueTask> GetActivityCommitStrategiesAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IIncidentStrategiesProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IIncidentStrategiesProvider.cs new file mode 100644 index 0000000..4a6dfad --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IIncidentStrategiesProvider.cs @@ -0,0 +1,14 @@ +using Elsa.Api.Client.Resources.IncidentStrategies.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Provides incident strategies. +/// +public interface IIncidentStrategiesProvider +{ + /// + /// Gets incident strategies. + /// + ValueTask> GetIncidentStrategiesAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/ILogPersistenceStrategyService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/ILogPersistenceStrategyService.cs new file mode 100644 index 0000000..cbb7eb7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/ILogPersistenceStrategyService.cs @@ -0,0 +1,15 @@ +using Elsa.Api.Client.Resources.LogPersistenceStrategies; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A services that provides log persistence strategies. +/// +public interface ILogPersistenceStrategyService +{ + /// + /// Gets the log persistence strategies. + /// + /// The cancellation token. + Task> GetLogPersistenceStrategiesAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IResilienceStrategyCatalog.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IResilienceStrategyCatalog.cs new file mode 100644 index 0000000..a314c59 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IResilienceStrategyCatalog.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// Provides resilience strategies. +/// +public interface IResilienceStrategyCatalog +{ + /// + /// Gets resilience strategies for the specified category. + /// + ValueTask> ListAsync(string category, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IStorageDriverService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IStorageDriverService.cs new file mode 100644 index 0000000..eb95c31 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IStorageDriverService.cs @@ -0,0 +1,16 @@ +using Elsa.Api.Client.Resources.StorageDrivers.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A services that provides storage drivers. +/// +public interface IStorageDriverService +{ + /// + /// Gets the storage drivers. + /// + /// + /// + Task> GetStorageDriversAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IVariableTypeService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IVariableTypeService.cs new file mode 100644 index 0000000..99624bd --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IVariableTypeService.cs @@ -0,0 +1,15 @@ +using Elsa.Api.Client.Resources.VariableTypes.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A services that provides variable types. +/// +public interface IVariableTypeService +{ + /// + /// Gets the variable types. + /// + /// The cancellation token. + Task> GetVariableTypesAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowActivationStrategyService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowActivationStrategyService.cs new file mode 100644 index 0000000..8cec784 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowActivationStrategyService.cs @@ -0,0 +1,15 @@ +using Elsa.Api.Client.Resources.WorkflowActivationStrategies.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A services that provides workflow activation strategies. +/// +public interface IWorkflowActivationStrategyService +{ + /// + /// Gets the workflow activation strategies. + /// + /// The cancellation token. + Task> GetWorkflowActivationStrategiesAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionEditorService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionEditorService.cs new file mode 100644 index 0000000..db0421d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionEditorService.cs @@ -0,0 +1,34 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Responses; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A service that can be used to manage workflow definitions. +/// +public interface IWorkflowDefinitionEditorService +{ + /// + /// Saves a workflow definition. + /// + Task> SaveAsync(WorkflowDefinition workflowDefinition, bool publish, Func? workflowSavedCallback = null, CancellationToken cancellationToken = default); + + /// + /// Publishes a workflow definition. + /// + Task PublishAsync(WorkflowDefinition workflowDefinition, Func? workflowPublishedCallback = null, CancellationToken cancellationToken = default); + + + /// + /// Retracts a workflow definition. + /// + Task> RetractAsync(WorkflowDefinition workflowDefinition, Func? workflowRetractedCallback = null, CancellationToken cancellationToken = default); + + /// + /// Exports a workflow definition. + /// + Task ExportAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionHistoryService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionHistoryService.cs new file mode 100644 index 0000000..997edf4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionHistoryService.cs @@ -0,0 +1,21 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A service that can be used to manage the history of workflow definitions. +/// +public interface IWorkflowDefinitionHistoryService +{ + /// + /// Retracts a workflow definition. + /// + Task> RetractAsync(WorkflowDefinition workflowDefinition, Func? workflowRetractedCallback = null, CancellationToken cancellationToken = default); + + /// + /// Reverts the specified workflow definition to the specified version. + /// + Task RevertAsync(WorkflowDefinitionVersion workflowDefinitionVersion, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionImporter.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionImporter.cs new file mode 100644 index 0000000..c20f25a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionImporter.cs @@ -0,0 +1,15 @@ +using Elsa.Studio.Workflows.Domain.Models; +using Microsoft.AspNetCore.Components.Forms; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A service that imports workflow definitions. +/// +public interface IWorkflowDefinitionImporter +{ + /// + /// Imports a set of files containing workflow definitions. + /// + Task> ImportFilesAsync(IReadOnlyList files, ImportOptions? options = null); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionService.cs new file mode 100644 index 0000000..45f3f91 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowDefinitionService.cs @@ -0,0 +1,120 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Responses; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Models; +using Refit; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A service that can be used to manage workflow definitions. +/// +public interface IWorkflowDefinitionService +{ + /// + /// Lists all workflow definitions. + /// + Task> ListAsync(ListWorkflowDefinitionsRequest request, VersionOptions? versionOptions = default, CancellationToken cancellationToken = default); + + /// + /// Finds a workflow definition by its ID. + /// + Task FindByDefinitionIdAsync(string definitionId, VersionOptions? versionOptions = default, CancellationToken cancellationToken = default); + + /// + /// Finds a workflow definition by its ID. + /// + Task FindByIdAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Finds all workflow definitions by their IDs. + /// + Task> FindManyByIdAsync(IEnumerable ids, CancellationToken cancellationToken = default); + + /// + /// Finds a workflow subgraph by workflow definition ID. + /// + Task FindSubgraphAsync(string id, string? parentNodeId = null, CancellationToken cancellationToken = default); + + /// + /// Returns all ancestor nodes for the specified child node. + /// + Task GetPathSegmentsAsync(string id, string? childNodeId = null, CancellationToken cancellationToken = default); + + /// + /// Deletes a workflow definition. + /// + Task DeleteAsync(string definitionId, CancellationToken cancellationToken = default); + + /// + /// Deletes a workflow definition version. + /// + Task DeleteVersionAsync(WorkflowDefinitionVersion workflowDefinitionVersion, CancellationToken cancellationToken = default); + + /// + /// Publishes a workflow definition. + /// + Task PublishAsync(string definitionId, CancellationToken cancellationToken = default); + + /// + /// Retracts a workflow definition. + /// + Task> RetractAsync(string definitionId, CancellationToken cancellationToken = default); + + /// + /// Deletes multiple workflow definitions. + /// + Task BulkDeleteAsync(IEnumerable definitionIds, CancellationToken cancellationToken = default); + + /// + /// Deletes multiple workflow definition versions. + /// + Task BulkDeleteVersionsAsync(IEnumerable workflowDefinitionVersions, CancellationToken cancellationToken = default); + + /// + /// Publishes multiple workflow definitions. + /// + Task BulkPublishAsync(IEnumerable definitionIds, CancellationToken cancellationToken = default); + + /// + /// Retracts multiple workflow definitions. + /// + Task BulkRetractAsync(IEnumerable definitionIds, CancellationToken cancellationToken = default); + + /// + /// Returns true if a workflow definition with the specified name exists. + /// + Task GetIsNameUniqueAsync(string name, string? definitionId = default, CancellationToken cancellationToken = default); + + /// + /// Generates a unique name for a workflow definition. + /// + Task GenerateUniqueNameAsync(CancellationToken cancellationToken = default); + + /// + /// Creates a new workflow definition. + /// + Task> CreateNewDefinitionAsync(string name, string? description = default, CancellationToken cancellationToken = default); + + /// + /// Exports a workflow definition. + /// + Task ExportDefinitionAsync(string definitionId, VersionOptions? versionOptions = default, CancellationToken cancellationToken = default); + + /// + /// Exports a set of workflow definitions. + /// + Task BulkExportDefinitionsAsync(IEnumerable ids, CancellationToken cancellationToken = default); + + /// + /// Updates the references of a workflow definition. + /// + Task UpdateReferencesAsync(string definitionId, CancellationToken cancellationToken = default); + + /// + /// Executes a workflow definition. + /// + Task ExecuteAsync(string definitionId, ExecuteWorkflowDefinitionRequest? request, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowInstanceService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowInstanceService.cs new file mode 100644 index 0000000..a9915fd --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowInstanceService.cs @@ -0,0 +1,22 @@ +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Requests; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Models; +using Refit; + +namespace Elsa.Studio.Workflows.Domain.Contracts; + +public interface IWorkflowInstanceService +{ + Task> ListAsync(ListWorkflowInstancesRequest request, CancellationToken cancellationToken = default); + Task DeleteAsync(string instanceId, CancellationToken cancellationToken = default); + Task BulkDeleteAsync(IEnumerable instanceIds, CancellationToken cancellationToken = default); + Task CancelAsync(string instanceId, CancellationToken cancellationToken = default); + Task BulkCancelAsync(BulkCancelWorkflowInstancesRequest request, CancellationToken cancellationToken = default); + Task GetAsync(string id, CancellationToken cancellationToken = default); + Task> GetJournalAsync(string instanceId, JournalFilter? filter = default, int? skip = default, int? take = default, CancellationToken cancellationToken = default); + Task ExportAsync(string id, CancellationToken cancellationToken = default); + Task BulkExportAsync(IEnumerable ids, CancellationToken cancellationToken = default); + Task BulkImportAsync(IEnumerable streamParts, CancellationToken cancellationToken = default); + Task> GetVariablesAsync(string instanceId, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowJsonDetector.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowJsonDetector.cs new file mode 100644 index 0000000..b163a53 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Contracts/IWorkflowJsonDetector.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Workflows.Domain.Contracts; + +/// +/// A service that detects whether a JSON string is a workflow definition. +/// +public interface IWorkflowJsonDetector +{ + /// + /// Checks whether the provided JSON is a workflow schema. + /// + bool IsWorkflowSchema(string json); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ActivityNodeExtensions.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ActivityNodeExtensions.cs new file mode 100644 index 0000000..57bb563 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ActivityNodeExtensions.cs @@ -0,0 +1,25 @@ +using Elsa.Api.Client.Shared.Models; + +namespace Elsa.Studio.Workflows.Domain.Extensions; + +/// +/// Provides extension methods for . +/// +public static class ActivityNodeExtensions +{ + /// + /// Returns a flattened list of the specified node and all its descendants. + /// + public static IEnumerable Flatten(this ActivityNode root) + { + yield return root; + + foreach (var node in root.Children) + { + var children = node.Flatten(); + + foreach (var child in children) + yield return child; + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ActivityRegistryExtensions.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ActivityRegistryExtensions.cs new file mode 100644 index 0000000..2b1003a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ActivityRegistryExtensions.cs @@ -0,0 +1,16 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ActivityRegistryExtensions +{ + /// + /// Returns a list of activity descriptors that are browsable. + /// + public static IEnumerable ListBrowsable(this IActivityRegistry activityRegistry) => + activityRegistry.List().Where(x => x.IsBrowsable).ToList(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ProblemDetailsExtensions.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ProblemDetailsExtensions.cs new file mode 100644 index 0000000..86e0554 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ProblemDetailsExtensions.cs @@ -0,0 +1,22 @@ +using Elsa.Studio.Workflows.Domain.Models; +using Refit; + +namespace Elsa.Studio.Workflows.Domain.Extensions; + +/// +/// Provides extension methods for . +/// +public static class ProblemDetailsExtensions +{ + /// + /// Converts a object to a object. + /// + public static ValidationErrors ToValidationErrors(this ProblemDetails problemDetails) + { + var validationErrors = + from pair in problemDetails.Errors + from message in pair.Value + select new ValidationError(message); + return new(validationErrors.ToList()); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ValidationApiExceptionExtensions.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ValidationApiExceptionExtensions.cs new file mode 100644 index 0000000..3d0c975 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Extensions/ValidationApiExceptionExtensions.cs @@ -0,0 +1,23 @@ +using Elsa.Studio.Workflows.Domain.Models; +using Refit; + +namespace Elsa.Studio.Workflows.Domain.Extensions; + +/// +/// Provides extension methods for . +/// +public static class ValidationApiExceptionExtensions +{ + /// + /// Gets the validation errors from a . + /// + public static ValidationErrors GetValidationErrors(this ValidationApiException e) + { + var problemDetails = e.Content; + + if (problemDetails != null) + return problemDetails.ToValidationErrors(); + + return problemDetails?.ToValidationErrors() ?? new ValidationErrors(new List { new(e.ReasonPhrase ?? "The server responded with a Bad Request status code. That's all I know.") }); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ActivityGraph.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ActivityGraph.cs new file mode 100644 index 0000000..bdfbf72 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ActivityGraph.cs @@ -0,0 +1,31 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Extensions; + +namespace Elsa.Studio.Workflows.Domain.Models; + +/// An activity and a lookup of its descendants. +public class ActivityGraph(JsonObject activity, IActivityVisitor activityVisitor) +{ + private IDictionary _activityNodeLookup = new Dictionary(); + + /// + /// The root activity. + /// + public JsonObject Activity { get; } = activity; + + /// + /// A lookup of activity nodes by ID. + /// + public IReadOnlyDictionary ActivityNodeLookup => _activityNodeLookup.AsReadOnly(); + + /// + /// Updates the activity node lookup. + /// + public async Task IndexAsync() + { + _activityNodeLookup = await activityVisitor.VisitAndMapAsync(Activity); + return this; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ActivityStats.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ActivityStats.cs new file mode 100644 index 0000000..a79c3cb --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ActivityStats.cs @@ -0,0 +1,37 @@ +namespace Elsa.Studio.Workflows.Domain.Models; + +/// +/// Represents a report of activity executions. +/// +public class ActivityStats +{ + /// + /// The number of times the activity has been started. + /// + public long Started { get; set; } + + /// + /// The number of times the activity has been completed. + /// + public long Completed { get; set; } + + /// + /// The number of times the activity has been uncompleted. + /// + public long Uncompleted { get; set; } + + /// + /// Whether the activity is blocked. + /// + public bool Blocked { get; set; } + + /// + /// Whether the activity has faulted. + /// + public bool Faulted { get; set; } + + /// + /// A collection of metadata associated with the activity statistics. + /// + public IDictionary? Metadata { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/EmbeddedActivity.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/EmbeddedActivity.cs new file mode 100644 index 0000000..9e7d1ef --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/EmbeddedActivity.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Workflows.Domain.Models; + +/// +/// Represents an embedded activity. +/// +/// The embedded activity. +/// The name of the property that contains the embedded activity. +public record EmbeddedActivity(JsonObject Activity, string PropertyName); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ExecuteWorkflowResult.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ExecuteWorkflowResult.cs new file mode 100644 index 0000000..a212751 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ExecuteWorkflowResult.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Workflows.Domain.Models; + +public record ExecuteWorkflowResult(string? WorkflowInstanceId, bool CannotStart); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ExpressionDescriptorProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ExpressionDescriptorProvider.cs new file mode 100644 index 0000000..fa43ac3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ExpressionDescriptorProvider.cs @@ -0,0 +1,35 @@ +using Elsa.Api.Client.Resources.Scripting.Models; + +namespace Elsa.Studio.Workflows.Domain.Models; + +/// +/// Provides expression descriptors that can be used as a cascading parameter. +/// +public class ExpressionDescriptorProvider +{ + private readonly IDictionary _expressionDescriptors = new Dictionary(); + + /// + /// Lists all expression descriptors. + /// + public IEnumerable ListDescriptors() => _expressionDescriptors.Values; + + /// + /// Adds an expression descriptor. + /// + public void Add(ExpressionDescriptor descriptor) => _expressionDescriptors[descriptor.Type] = descriptor; + + /// + /// Gets an expression descriptor by type. + /// + public ExpressionDescriptor? GetByType(string type) => _expressionDescriptors.TryGetValue(type, out var descriptor) ? descriptor : default; + + /// + /// Adds a range of expression descriptors. + /// + public void AddRange(IEnumerable descriptors) + { + foreach (var descriptor in descriptors) + Add(descriptor); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/FileDownload.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/FileDownload.cs new file mode 100644 index 0000000..58beffb --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/FileDownload.cs @@ -0,0 +1,6 @@ +namespace Elsa.Studio.Workflows.Domain.Models; + +/// +/// Represents a file download. +/// +public record FileDownload(string FileName, Stream Content); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ImportOptions.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ImportOptions.cs new file mode 100644 index 0000000..16d2c62 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ImportOptions.cs @@ -0,0 +1,11 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; + +namespace Elsa.Studio.Workflows.Domain.Models; + +public class ImportOptions +{ + public int MaxAllowedSize { get; set; } = 1024 * 1024 * 10; // 10 MB + public string? DefinitionId { get; set; } + public Func? ImportedCallback { get; set; } + public Func ErrorCallback { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ValidationError.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ValidationError.cs new file mode 100644 index 0000000..722ee90 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ValidationError.cs @@ -0,0 +1,13 @@ +namespace Elsa.Studio.Workflows.Domain.Models; + +/// +/// Represents a validation error. +/// +/// +public record ValidationError(string ErrorMessage) +{ + /// + /// Returns the error message. + /// + public override string ToString() => ErrorMessage; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ValidationErrors.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ValidationErrors.cs new file mode 100644 index 0000000..9350419 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/ValidationErrors.cs @@ -0,0 +1,6 @@ +namespace Elsa.Studio.Workflows.Domain.Models; + +/// +/// Represents a collection of validation errors. +/// +public record ValidationErrors(IReadOnlyCollection Errors); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowDefinitionVersion.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowDefinitionVersion.cs new file mode 100644 index 0000000..59639be --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowDefinitionVersion.cs @@ -0,0 +1,21 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; + +namespace Elsa.Studio.Workflows.Domain.Models; + +public record WorkflowDefinitionVersion(string WorkflowDefinitionId, string WorkflowDefinitionVersionId, int Version) +{ + public static WorkflowDefinitionVersion FromDefinition(WorkflowDefinition workflowDefinition) + { + return new(workflowDefinition.DefinitionId, workflowDefinition.Id, workflowDefinition.Version); + } + + public static WorkflowDefinitionVersion FromDefinitionSummary(WorkflowDefinitionSummary workflowDefinitionSummary) + { + return new(workflowDefinitionSummary.DefinitionId, workflowDefinitionSummary.Id, workflowDefinitionSummary.Version); + } + + public static WorkflowDefinitionVersion FromDefinitionModel(WorkflowDefinitionModel model) + { + return new(model.DefinitionId, model.Id, model.Version); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportFailure.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportFailure.cs new file mode 100644 index 0000000..64efeb4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportFailure.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Workflows.Domain.Models; + +public record WorkflowImportFailure(string ErrorMessage, WorkflowImportFailureType FailureType); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportFailureType.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportFailureType.cs new file mode 100644 index 0000000..2d7d1da --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportFailureType.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Workflows.Domain.Models; + +public enum WorkflowImportFailureType +{ + Exception, + InvalidSchema +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportResult.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportResult.cs new file mode 100644 index 0000000..6abaad0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Models/WorkflowImportResult.cs @@ -0,0 +1,11 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; + +namespace Elsa.Studio.Workflows.Domain.Models; + +public class WorkflowImportResult +{ + public string FileName { get; set; } + public WorkflowDefinition? WorkflowDefinition { get; set; } + public WorkflowImportFailure? Failure { get; set; } + public bool IsSuccess => Failure == null; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ActivityRegistryRefreshed.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ActivityRegistryRefreshed.cs new file mode 100644 index 0000000..115344d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ActivityRegistryRefreshed.cs @@ -0,0 +1,10 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +/// +/// Represents a notification published when the activity registry is refreshed. +/// +public class ActivityRegistryRefreshed : INotification +{ +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionReverted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionReverted.cs new file mode 100644 index 0000000..507a3a7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionReverted.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionReverted(ICollection WorkflowDefinitionVersions); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionReverting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionReverting.cs new file mode 100644 index 0000000..9fc7780 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionReverting.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionReverting(ICollection WorkflowDefinitionVersions); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionVersionsDeleted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionVersionsDeleted.cs new file mode 100644 index 0000000..1b49713 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionVersionsDeleted.cs @@ -0,0 +1,6 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionVersionsDeleted(ICollection Versions) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionVersionsDeleting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionVersionsDeleting.cs new file mode 100644 index 0000000..fea11d6 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionVersionsDeleting.cs @@ -0,0 +1,6 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionVersionsDeleting(ICollection Versions) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsDeleted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsDeleted.cs new file mode 100644 index 0000000..454246f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsDeleted.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionsDeleted(ICollection WorkflowDefinitionIds) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsDeleting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsDeleting.cs new file mode 100644 index 0000000..5b5ab6e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsDeleting.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionsDeleting(ICollection WorkflowDefinitionIds) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsPublished.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsPublished.cs new file mode 100644 index 0000000..138aead --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsPublished.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionsPublished(ICollection WorkflowDefinitionIds) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsPublishing.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsPublishing.cs new file mode 100644 index 0000000..42dc9c7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsPublishing.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionsPublishing(ICollection WorkflowDefinitionIds) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsRetracted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsRetracted.cs new file mode 100644 index 0000000..73f22e1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsRetracted.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionsRetracted(ICollection WorkflowDefinitionIds) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsRetracting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsRetracting.cs new file mode 100644 index 0000000..dd93aa9 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/BulkWorkflowDefinitionsRetracting.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record BulkWorkflowDefinitionsRetracting(ICollection WorkflowDefinitionIds) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedFile.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedFile.cs new file mode 100644 index 0000000..47e24fa --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedFile.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Contracts; +using JetBrains.Annotations; +using Microsoft.AspNetCore.Components.Forms; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +[UsedImplicitly] +public record ImportedFile(IBrowserFile File) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedJson.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedJson.cs new file mode 100644 index 0000000..08d3973 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedJson.cs @@ -0,0 +1,7 @@ +using Elsa.Studio.Contracts; +using JetBrains.Annotations; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +[UsedImplicitly] +public record ImportedJson(string Json) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedWorkflowDefinition.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedWorkflowDefinition.cs new file mode 100644 index 0000000..513b593 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportedWorkflowDefinition.cs @@ -0,0 +1,6 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record ImportedWorkflowDefinition(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingFile.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingFile.cs new file mode 100644 index 0000000..18b1336 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingFile.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Contracts; +using JetBrains.Annotations; +using Microsoft.AspNetCore.Components.Forms; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +[UsedImplicitly] +public record ImportingFile(IBrowserFile File) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingJson.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingJson.cs new file mode 100644 index 0000000..4e09e8c --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingJson.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Contracts; +using JetBrains.Annotations; +using Microsoft.AspNetCore.Components.Forms; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +[UsedImplicitly] +public record ImportingJson(string Json) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingWorkflowDefinition.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingWorkflowDefinition.cs new file mode 100644 index 0000000..505494b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/ImportingWorkflowDefinition.cs @@ -0,0 +1,6 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record ImportingWorkflowDefinition(WorkflowDefinitionModel WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionDeleted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionDeleted.cs new file mode 100644 index 0000000..26bdbd2 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionDeleted.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionDeleted(string WorkflowDefinitionId) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionDeleting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionDeleting.cs new file mode 100644 index 0000000..711b4c6 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionDeleting.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionDeleting(string WorkflowDefinitionId) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionExported.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionExported.cs new file mode 100644 index 0000000..837f648 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionExported.cs @@ -0,0 +1,7 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionExported(WorkflowDefinition WorkflowDefinition, FileDownload FileDownload) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionExporting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionExporting.cs new file mode 100644 index 0000000..b4c40c5 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionExporting.cs @@ -0,0 +1,6 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionExporting(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdExported.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdExported.cs new file mode 100644 index 0000000..d97944a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdExported.cs @@ -0,0 +1,7 @@ +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionIdExported(string WorkflowDefinitionId, VersionOptions? VersionOptions, FileDownload FileDownload) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdExporting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdExporting.cs new file mode 100644 index 0000000..3855693 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdExporting.cs @@ -0,0 +1,6 @@ +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionIdExporting(string WorkflowDefinitionId, VersionOptions? VersionOptions) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdPublishing.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdPublishing.cs new file mode 100644 index 0000000..5a1e9a5 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdPublishing.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +/// +/// Represents a notification sent when a workflow definition is about to be published by its ID. +/// +public record WorkflowDefinitionIdPublishing(string WorkflowDefinitionId) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdRetracting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdRetracting.cs new file mode 100644 index 0000000..17a7864 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdRetracting.cs @@ -0,0 +1,5 @@ +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionIdRetracting(string WorkflowDefinitionId) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdRetractingFailed.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdRetractingFailed.cs new file mode 100644 index 0000000..eaf1ded --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionIdRetractingFailed.cs @@ -0,0 +1,6 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionIdRetractingFailed(string WorkflowDefinitionId, ValidationErrors Errors) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublished.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublished.cs new file mode 100644 index 0000000..3906193 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublished.cs @@ -0,0 +1,7 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +/// Represents a notification sent when a workflow definition is published. +public record WorkflowDefinitionPublished(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublishing.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublishing.cs new file mode 100644 index 0000000..a8fde73 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublishing.cs @@ -0,0 +1,7 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +/// Represents a notification sent when a workflow definition is about to be published. +public record WorkflowDefinitionPublishing(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublishingFailed.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublishingFailed.cs new file mode 100644 index 0000000..4c169ba --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionPublishingFailed.cs @@ -0,0 +1,10 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +/// +/// A notification sent when a workflow definition failed to publish. +/// +public record WorkflowDefinitionPublishingFailed(WorkflowDefinition WorkflowDefinition, ValidationErrors Errors) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetracted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetracted.cs new file mode 100644 index 0000000..576e360 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetracted.cs @@ -0,0 +1,6 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionRetracted(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetracting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetracting.cs new file mode 100644 index 0000000..dfcbaf0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetracting.cs @@ -0,0 +1,6 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionRetracting(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetractingFailed.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetractingFailed.cs new file mode 100644 index 0000000..34efc63 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionRetractingFailed.cs @@ -0,0 +1,7 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionRetractingFailed(WorkflowDefinition WorkflowDefinition, ValidationErrors Errors) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionReverted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionReverted.cs new file mode 100644 index 0000000..4a46f94 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionReverted.cs @@ -0,0 +1,6 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionReverted(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSaved.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSaved.cs new file mode 100644 index 0000000..40c8bcb --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSaved.cs @@ -0,0 +1,7 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +/// Represents a notification sent when a workflow definition has been saved. +public record WorkflowDefinitionSaved(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSaving.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSaving.cs new file mode 100644 index 0000000..b1665d7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSaving.cs @@ -0,0 +1,7 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +/// Represents a notification sent when a workflow definition is about to be saved. +public record WorkflowDefinitionSaving(WorkflowDefinition WorkflowDefinition) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSavingFailed.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSavingFailed.cs new file mode 100644 index 0000000..ae43807 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionSavingFailed.cs @@ -0,0 +1,10 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +/// +/// A notification sent when a workflow definition failed to save. +/// +public record WorkflowDefinitionSavingFailed(WorkflowDefinition WorkflowDefinition, ValidationErrors Errors) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionDeleted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionDeleted.cs new file mode 100644 index 0000000..9f23ebd --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionDeleted.cs @@ -0,0 +1,6 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionVersionDeleted(WorkflowDefinitionVersion WorkflowDefinitionVersion) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionDeleting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionDeleting.cs new file mode 100644 index 0000000..e3ee2b7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionDeleting.cs @@ -0,0 +1,6 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionVersionDeleting(WorkflowDefinitionVersion WorkflowDefinitionVersion) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionReverted.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionReverted.cs new file mode 100644 index 0000000..5253120 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionReverted.cs @@ -0,0 +1,6 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionVersionReverted(WorkflowDefinitionVersion WorkflowDefinitionVersion) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionReverting.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionReverting.cs new file mode 100644 index 0000000..14aba7d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Notifications/WorkflowDefinitionVersionReverting.cs @@ -0,0 +1,6 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Domain.Notifications; + +public record WorkflowDefinitionVersionReverting(WorkflowDefinitionVersion WorkflowDefinitionVersion) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/PortProviders/ActivityPortProviderBase.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/PortProviders/ActivityPortProviderBase.cs new file mode 100644 index 0000000..1ae866d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/PortProviders/ActivityPortProviderBase.cs @@ -0,0 +1,45 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Humanizer; + +namespace Elsa.Studio.Workflows.Domain.Providers; + +/// +public abstract class ActivityPortProviderBase : IActivityPortProvider +{ + /// + public virtual double Priority => 0; + + /// + public abstract bool GetSupportsActivityType(PortProviderContext context); + + /// + public abstract IEnumerable GetPorts(PortProviderContext context); + + /// + public virtual JsonObject? ResolvePort(string portName, PortProviderContext context) + { + var activity = context.Activity; + var propName = portName.Camelize(); + return activity.GetProperty(propName)?.AsObject(); + } + + /// + public virtual void AssignPort(string portName, JsonObject activity, PortProviderContext context) + { + var container = context.Activity; + var propName = portName.Camelize(); + container.SetProperty(activity, propName); + } + + /// + public virtual void ClearPort(string portName, PortProviderContext context) + { + var container = context.Activity; + var propName = portName.Camelize(); + container.Remove(propName); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/PortProviders/DefaultActivityPortProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/PortProviders/DefaultActivityPortProvider.cs new file mode 100644 index 0000000..53114ff --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/PortProviders/DefaultActivityPortProvider.cs @@ -0,0 +1,23 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Providers; + +/// +/// A default implementation of that returns the ports defined by the activity descriptor. +/// +public class DefaultActivityPortProvider : ActivityPortProviderBase +{ + /// + public override double Priority => -1000; + + /// + public override bool GetSupportsActivityType(PortProviderContext context) => true; + + /// + public override IEnumerable GetPorts(PortProviderContext context) + { + return context.ActivityDescriptor.Ports.ToList(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityDisplaySettingsRegistry.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityDisplaySettingsRegistry.cs new file mode 100644 index 0000000..44236c4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityDisplaySettingsRegistry.cs @@ -0,0 +1,53 @@ +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +public class DefaultActivityDisplaySettingsRegistry : IActivityDisplaySettingsRegistry +{ + private readonly IEnumerable _providers; + private IDictionary? _settings; + + /// + /// Initializes a new instance of the class. + /// + public DefaultActivityDisplaySettingsRegistry(IEnumerable providers) + { + _providers = providers; + } + + private static ActivityDisplaySettings DefaultSettings { get; set; } = new(DefaultActivityColors.Default); + + /// + public ActivityDisplaySettings GetSettings(string activityType) + { + var dictionary = GetSettingsDictionary(); + return dictionary.TryGetValue(activityType, out var settings) ? settings : DefaultSettings; + } + + /// + public void MarkStale() + { + _settings = null; + } + + private IDictionary GetSettingsDictionary() + { + if(_settings != null) + return _settings; + + var settings = new Dictionary(); + + foreach (var provider in _providers) + { + var providerSettings = provider.GetSettings(); + + foreach (var (activityType, activityDisplaySettings) in providerSettings) + settings[activityType] = activityDisplaySettings; + } + + _settings = settings; + return _settings; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityNameGenerator.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityNameGenerator.cs new file mode 100644 index 0000000..1230b98 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityNameGenerator.cs @@ -0,0 +1,38 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +public class DefaultActivityNameGenerator : IActivityNameGenerator +{ + /// + public bool GetNameExists(IEnumerable activities, string name) + { + return activities.Any(x => x.GetName() == name); + } + + /// + public string GenerateNextName(IEnumerable activities, ActivityDescriptor activityDescriptor) + { + var max = 10000; + var enumerable = activities as JsonObject[] ?? activities.ToArray(); + var count = GetNextNumber(enumerable, activityDescriptor); + + while (count++ < max) + { + var nextName = $"{activityDescriptor.Name}{count}"; + if (!GetNameExists(enumerable, nextName)) + return nextName; + } + + throw new Exception("Could not generate a unique name."); + } + + private static int GetNextNumber(IEnumerable activities, ActivityDescriptor activityDescriptor) + { + return activities.Count(x => x.GetTypeName() == activityDescriptor.TypeName); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityPortService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityPortService.cs new file mode 100644 index 0000000..b108257 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityPortService.cs @@ -0,0 +1,34 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +public class DefaultActivityPortService : IActivityPortService +{ + private readonly IEnumerable _providers; + + /// + /// Initializes a new instance of the class. + /// + public DefaultActivityPortService(IEnumerable providers) + { + _providers = providers; + } + + /// + public IActivityPortProvider GetProvider(PortProviderContext context) + { + var activityType = context.ActivityDescriptor.TypeName; + var provider = _providers.Where(x => x.GetSupportsActivityType(context)).MaxBy(x => x.Priority); + return provider ?? throw new Exception($"No port provider found for activity type '{activityType}'."); + } + + /// + public IEnumerable GetPorts(PortProviderContext context) + { + var provider = GetProvider(context); + return provider.GetPorts(context); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityRegistry.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityRegistry.cs new file mode 100644 index 0000000..4366d3b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityRegistry.cs @@ -0,0 +1,82 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Notifications; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +public class DefaultActivityRegistry : IActivityRegistry +{ + private readonly IActivityRegistryProvider _provider; + private readonly IMediator _mediator; + private Dictionary<(string ActivityTypeName, int Version), ActivityDescriptor> _activityDescriptors = new(); + private readonly SemaphoreSlim _semaphore = new(1, 1); + private bool _isStale = true; + + /// + /// Initializes a new instance of the class. + /// + public DefaultActivityRegistry(IActivityRegistryProvider provider, IMediator mediator) + { + _provider = provider; + _mediator = mediator; + } + + /// + public async Task RefreshAsync(CancellationToken cancellationToken = default) + { + var descriptors = await _provider.ListAsync(cancellationToken); + _activityDescriptors = descriptors.ToDictionary(x => (x.TypeName, x.Version)); + _isStale = false; + await _mediator.NotifyAsync(new ActivityRegistryRefreshed(), cancellationToken); + } + + /// + public async Task EnsureLoadedAsync(CancellationToken cancellationToken = default) + { + await _semaphore.WaitAsync(cancellationToken); + + try + { + if (!_isStale) + return; + + await RefreshAsync(cancellationToken); + } + finally + { + _semaphore.Release(); + } + } + + /// + public IEnumerable List() + { + // Return the latest version of each activity descriptor from _activityDescriptors. + return _activityDescriptors.Values + .GroupBy(activityDescriptor => activityDescriptor.TypeName) + .Select(grouping => grouping.OrderByDescending(y => y.Version).First()); + } + + /// + public ActivityDescriptor? Find(string activityType, int? version = default) + { + version ??= 1; + return _activityDescriptors.GetValueOrDefault((activityType, version.Value)); + } + + /// + public IEnumerable FindAll(string activityType) + { + return _activityDescriptors + .Where(kvp => kvp.Key.ActivityTypeName == activityType) + .Select(kvp => kvp.Value); + } + + /// + public void MarkStale() + { + _isStale = true; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityVisitor.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityVisitor.cs new file mode 100644 index 0000000..c4c226d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/DefaultActivityVisitor.cs @@ -0,0 +1,64 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +public class DefaultActivityVisitor : IActivityVisitor +{ + private readonly IEnumerable _portResolvers; + + /// + /// Initializes a new instance of the class. + /// + public DefaultActivityVisitor(IEnumerable portResolvers) + { + _portResolvers = portResolvers.OrderByDescending(x => x.Priority).ToList(); + } + + /// + public async Task VisitAsync(JsonObject activity, CancellationToken cancellationToken = default) + { + var collectedActivities = new HashSet(new[] { activity }); + var graph = new ActivityNode(activity); + var collectedNodes = new HashSet(new[] { graph }); + await VisitRecursiveAsync((graph, activity), collectedActivities, collectedNodes, cancellationToken); + return graph; + } + + private async Task VisitRecursiveAsync((ActivityNode Node, JsonObject Activity) pair, HashSet collectedActivities, HashSet collectedNodes, CancellationToken cancellationToken) + { + await VisitPortsRecursiveAsync(pair, collectedActivities, collectedNodes, cancellationToken); + } + + private async Task VisitPortsRecursiveAsync((ActivityNode Node, JsonObject Activity) pair, HashSet collectedActivities, HashSet collectedNodes, CancellationToken cancellationToken) + { + var resolver = _portResolvers.FirstOrDefault(x => x.GetSupportsActivity(pair.Activity)); + + if (resolver == null) + return; + + var embeddedActivities = await resolver.GetActivitiesAsync(pair.Activity, cancellationToken); + + foreach (var embeddedActivity in embeddedActivities) + { + // Continue if the specified activity was already encountered. + if (collectedActivities.Contains(embeddedActivity.Activity)) + continue; + + var childNode = collectedNodes.FirstOrDefault(x => x.Activity == embeddedActivity.Activity); + + if (childNode == null) + { + childNode = new ActivityNode(embeddedActivity.Activity, embeddedActivity.PropertyName); + collectedNodes.Add(childNode); + } + + childNode.Parents.Add(pair.Node); + pair.Node.Children.Add(childNode); + collectedActivities.Add(embeddedActivity.Activity); + await VisitRecursiveAsync((childNode, embeddedActivity.Activity), collectedActivities, collectedNodes, cancellationToken); + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RandomLongIdentityGenerator.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RandomLongIdentityGenerator.cs new file mode 100644 index 0000000..d1b495c --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RandomLongIdentityGenerator.cs @@ -0,0 +1,19 @@ +using System.Security.Cryptography; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// Generates a unique identifier using a random long value. +/// +public class RandomLongIdentityGenerator : IIdentityGenerator +{ + /// + public string GenerateId() + { + var bytes = new byte[8]; + RandomNumberGenerator.Fill(bytes); + var randomLong = BitConverter.ToInt64(bytes, 0); + return randomLong.ToString("x"); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteActivityExecutionService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteActivityExecutionService.cs new file mode 100644 index 0000000..d633886 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteActivityExecutionService.cs @@ -0,0 +1,73 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityExecutions.Contracts; +using Elsa.Api.Client.Resources.ActivityExecutions.Models; +using Elsa.Api.Client.Resources.ActivityExecutions.Requests; +using Elsa.Api.Client.Resources.Resilience.Contracts; +using Elsa.Api.Client.Resources.Resilience.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// An activity execution service that uses a remote backend to retrieve activity execution reports. +/// +public class RemoteActivityExecutionService(IBackendApiClientProvider backendApiClientProvider) : IActivityExecutionService +{ + /// + public async Task GetReportAsync(string workflowInstanceId, JsonObject containerActivity, CancellationToken cancellationToken = default) + { + var activityNodeIds = containerActivity.GetActivities().Select(x => x.GetNodeId()).ToList(); + var request = new GetActivityExecutionReportRequest + { + WorkflowInstanceId = workflowInstanceId, + ActivityNodeIds = activityNodeIds + }; + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + return await api.GetReportAsync(request, cancellationToken); + } + + /// + public async Task> ListAsync(string workflowInstanceId, string activityNodeId, CancellationToken cancellationToken = default) + { + var request = new ListActivityExecutionsRequest + { + WorkflowInstanceId = workflowInstanceId, + ActivityNodeId = activityNodeId + }; + + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(request, cancellationToken); + return response.Items; + } + + /// + public async Task> ListSummariesAsync(string workflowInstanceId, string activityNodeId, CancellationToken cancellationToken = default) + { + var request = new ListActivityExecutionsRequest + { + WorkflowInstanceId = workflowInstanceId, + ActivityNodeId = activityNodeId + }; + + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListSummariesAsync(request, cancellationToken); + return response.Items; + } + + /// + public async Task GetAsync(string id, CancellationToken cancellationToken = default) + { + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + return await api.GetAsync(id, cancellationToken); + } + + /// + public async Task> GetRetriesAsync(string activityInstanceId, int? skip = null, int? take = null, CancellationToken cancellationToken = default) + { + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + return await api.ListAsync(activityInstanceId, skip, take, cancellationToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteActivityRegistryProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteActivityRegistryProvider.cs new file mode 100644 index 0000000..c1c62bd --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteActivityRegistryProvider.cs @@ -0,0 +1,26 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Contracts; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.ActivityDescriptors.Requests; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// An activity registry provider that uses a remote backend to retrieve activity descriptors. +/// +public class RemoteActivityRegistryProvider(IBackendApiClientProvider remoteBackendApiClientProvider) : IActivityRegistryProvider +{ + /// + public async Task> ListAsync(CancellationToken cancellationToken = default) + { + var api = await remoteBackendApiClientProvider.GetApiAsync(cancellationToken); + var request = new ListActivityDescriptorsRequest + { + Refresh = true + }; + var response = await api.ListAsync(request, cancellationToken); + + return response.Items; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteCommitStrategiesProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteCommitStrategiesProvider.cs new file mode 100644 index 0000000..7721cb7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteCommitStrategiesProvider.cs @@ -0,0 +1,41 @@ +using Elsa.Api.Client.Resources.CommitStrategies.Contracts; +using Elsa.Api.Client.Resources.CommitStrategies.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +public class RemoteCommitStrategiesProvider(IBackendApiClientProvider backendApiClientProvider) : ICommitStrategiesProvider +{ + private ICollection? _workflowCommitStrategies; + private ICollection? _activityCommitStrategies; + + /// + public async ValueTask> GetWorkflowCommitStrategiesAsync(CancellationToken cancellationToken = default) + { + if (_workflowCommitStrategies == null) + { + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListWorkflowStrategiesAsync(cancellationToken); + + _workflowCommitStrategies = response.Items; + } + + return _workflowCommitStrategies; + } + + /// + public async ValueTask> GetActivityCommitStrategiesAsync(CancellationToken cancellationToken = default) + { + if (_activityCommitStrategies == null) + { + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListActivityStrategiesAsync(cancellationToken); + + _activityCommitStrategies = response.Items; + } + + return _activityCommitStrategies; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteIncidentStrategiesProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteIncidentStrategiesProvider.cs new file mode 100644 index 0000000..e8ca521 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteIncidentStrategiesProvider.cs @@ -0,0 +1,21 @@ +using Elsa.Api.Client.Resources.IncidentStrategies.Contracts; +using Elsa.Api.Client.Resources.IncidentStrategies.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// Provides incident strategies from a remote server. +/// +public class RemoteIncidentStrategiesProvider(IBackendApiClientProvider backendApiClientProvider) : IIncidentStrategiesProvider +{ + /// + public async ValueTask> GetIncidentStrategiesAsync(CancellationToken cancellationToken = default) + { + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(cancellationToken); + + return response.Items; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteLogPersistenceStrategyService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteLogPersistenceStrategyService.cs new file mode 100644 index 0000000..3a9f5ad --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteLogPersistenceStrategyService.cs @@ -0,0 +1,24 @@ +using Elsa.Api.Client.Resources.LogPersistenceStrategies; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +public class RemoteLogPersistenceStrategyService(IBackendApiClientProvider backendApiClientProvider) : ILogPersistenceStrategyService +{ + private ICollection? _descriptors; + + /// + public async Task> GetLogPersistenceStrategiesAsync(CancellationToken cancellationToken = default) + { + if (_descriptors == null) + { + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(cancellationToken); + _descriptors = response.Items; + } + + return _descriptors; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteResilienceStrategyCatalog.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteResilienceStrategyCatalog.cs new file mode 100644 index 0000000..76a77e1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteResilienceStrategyCatalog.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.Resilience.Contracts; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +public class RemoteResilienceStrategyCatalog(IBackendApiClientProvider backendApiClientProvider) : IResilienceStrategyCatalog +{ + /// + public async ValueTask> ListAsync(string category, CancellationToken cancellationToken = default) + { + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(category, cancellationToken); + + return response.Items; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteServerInformationProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteServerInformationProvider.cs new file mode 100644 index 0000000..fa94867 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteServerInformationProvider.cs @@ -0,0 +1,31 @@ +using Elsa.Api.Client.Resources.Package.Contracts; +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// Provides information about a remote server. +/// +public class RemoteServerInformationProvider : IServerInformationProvider +{ + private readonly IBackendApiClientProvider _backendApiClientProvider; + + /// + /// Initializes a new instance of the class. + /// + public RemoteServerInformationProvider(IBackendApiClientProvider backendApiClientProvider) + { + _backendApiClientProvider = backendApiClientProvider; + } + + /// + public async ValueTask GetInfoAsync(CancellationToken cancellationToken = default) + { + var api = await _backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.GetAsync(cancellationToken); + var packageVersion = response.PackageVersion.ToString(); + + return new (PackageVersion: packageVersion); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteStorageDriverService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteStorageDriverService.cs new file mode 100644 index 0000000..9680e10 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteStorageDriverService.cs @@ -0,0 +1,31 @@ +using Elsa.Api.Client.Resources.StorageDrivers.Contracts; +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A storage driver service that uses a remote backend to retrieve storage drivers. +/// +public class RemoteStorageDriverService : IStorageDriverService +{ + private readonly IBackendApiClientProvider _backendApiClientProvider; + + /// + /// Initializes a new instance of the class. + /// + public RemoteStorageDriverService(IBackendApiClientProvider backendApiClientProvider) + { + _backendApiClientProvider = backendApiClientProvider; + } + + /// + public async Task> GetStorageDriversAsync(CancellationToken cancellationToken = default) + { + var api = await _backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(cancellationToken); + + return response.Items; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteVariableTypeService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteVariableTypeService.cs new file mode 100644 index 0000000..929cdf2 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteVariableTypeService.cs @@ -0,0 +1,30 @@ +using Elsa.Api.Client.Resources.VariableTypes.Contracts; +using Elsa.Api.Client.Resources.VariableTypes.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A variable type service that uses a remote backend to retrieve variable types. +/// +public class RemoteVariableTypeService : IVariableTypeService +{ + private readonly IBackendApiClientProvider _backendApiClientProvider; + + /// + /// Initializes a new instance of the class. + /// + public RemoteVariableTypeService(IBackendApiClientProvider backendApiClientProvider) + { + _backendApiClientProvider = backendApiClientProvider; + } + + /// + public async Task> GetVariableTypesAsync(CancellationToken cancellationToken = default) + { + var api = await _backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(cancellationToken); + return response.Items; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteWorkflowActivationStrategyService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteWorkflowActivationStrategyService.cs new file mode 100644 index 0000000..00228ed --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteWorkflowActivationStrategyService.cs @@ -0,0 +1,20 @@ +using Elsa.Api.Client.Resources.WorkflowActivationStrategies.Contracts; +using Elsa.Api.Client.Resources.WorkflowActivationStrategies.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A workflow activation strategy service that uses a remote backend to retrieve workflow activation strategies. +/// +public class RemoteWorkflowActivationStrategyService(IBackendApiClientProvider backendApiClientProvider) : IWorkflowActivationStrategyService +{ + /// + public async Task> GetWorkflowActivationStrategiesAsync(CancellationToken cancellationToken = default) + { + var api = await backendApiClientProvider.GetApiAsync(cancellationToken); + var response = await api.ListAsync(cancellationToken); + return response.Items; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteWorkflowInstanceService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteWorkflowInstanceService.cs new file mode 100644 index 0000000..e1b0be3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/RemoteWorkflowInstanceService.cs @@ -0,0 +1,130 @@ +using System.Net; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.WorkflowInstances.Contracts; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Requests; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Refit; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A workflow instance service that uses a remote backend to retrieve workflow instances. +/// +public class RemoteWorkflowInstanceService : IWorkflowInstanceService +{ + private readonly IBackendApiClientProvider _backendApiClientProvider; + + /// + /// Initializes a new instance of the class. + /// + public RemoteWorkflowInstanceService(IBackendApiClientProvider backendApiClientProvider) + { + _backendApiClientProvider = backendApiClientProvider; + } + + /// + public async Task> ListAsync(ListWorkflowInstancesRequest request, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + return await api.ListAsync(request, cancellationToken); + } + + /// + public async Task DeleteAsync(string instanceId, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await api.DeleteAsync(instanceId, cancellationToken); + } + + /// + public async Task BulkDeleteAsync(IEnumerable instanceIds, CancellationToken cancellationToken = default) + { + var request = new BulkDeleteWorkflowInstancesRequest + { + Ids = instanceIds.ToList() + }; + var api = await GetApiAsync(cancellationToken); + await api.BulkDeleteAsync(request, cancellationToken); + } + + /// + public async Task CancelAsync(string instanceId, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await api.CancelAsync(instanceId, cancellationToken); + } + + /// + public async Task BulkCancelAsync(BulkCancelWorkflowInstancesRequest request, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await api.BulkCancelAsync(request, cancellationToken); + } + + /// + public async Task GetAsync(string id, CancellationToken cancellationToken = default) + { + try + { + var api = await GetApiAsync(cancellationToken); + return await api.GetAsync(id, cancellationToken); + } + catch (ApiException e) when (e.StatusCode == HttpStatusCode.NotFound) + { + return null; + } + } + + /// + public async Task> GetJournalAsync(string instanceId, JournalFilter? filter = null, int? skip = null, int? take = null, CancellationToken cancellationToken = default) + { + var request = new GetFilteredJournalRequest + { + Filter = filter + }; + var api = await GetApiAsync(cancellationToken); + return await api.GetFilteredJournalAsync(instanceId, request, skip, take, cancellationToken); + } + + /// + public async Task ExportAsync(string id, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + var response = await api.ExportAsync(id, cancellationToken); + var fileName = response.GetDownloadedFileNameOrDefault($"workflow-instance-{id}.json"); + + return new(fileName, response.Content!); + } + + /// + public async Task BulkExportAsync(IEnumerable ids, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + var request = new BulkExportWorkflowInstancesRequest(ids.ToArray()); + var response = await api.BulkExportAsync(request, cancellationToken); + var fileName = response.GetDownloadedFileNameOrDefault("workflow-instances.zip"); + return new(fileName, response.Content!); + } + + /// + public async Task BulkImportAsync(IEnumerable streamParts, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + var response = await api.BulkImportAsync(streamParts.ToList(), cancellationToken); + return response.Count; + } + + /// + public async Task> GetVariablesAsync(string instanceId, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + var response = await api.GetVariablesAsync(instanceId, cancellationToken); + return response.Items; + } + + private async Task GetApiAsync(CancellationToken cancellationToken = default) => await _backendApiClientProvider.GetApiAsync(cancellationToken); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/SchemaWorkflowJsonDetector.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/SchemaWorkflowJsonDetector.cs new file mode 100644 index 0000000..d36b95b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/SchemaWorkflowJsonDetector.cs @@ -0,0 +1,27 @@ +using System.Text.Json; +using Elsa.Studio.Workflows.Domain.Contracts; +using JetBrains.Annotations; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A service that detects whether a JSON string is a workflow definition using a schema. +/// +[UsedImplicitly] +public class SchemaWorkflowJsonDetector : IWorkflowJsonDetector +{ + /// + public bool IsWorkflowSchema(string json) + { + var jsonDocument = JsonDocument.Parse(json); + var rootElement = jsonDocument.RootElement; + + if (!rootElement.TryGetProperty("$schema", out var schemaUrl)) + return false; + + if (schemaUrl.GetString()?.StartsWith("https://elsaworkflows.io/schemas/workflow-definition") == false) + return false; + + return true; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/ShortGuidActivityIdGenerator.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/ShortGuidActivityIdGenerator.cs new file mode 100644 index 0000000..70420b1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/ShortGuidActivityIdGenerator.cs @@ -0,0 +1,13 @@ +using DEDrake; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// Generates unique activity IDs using . +/// +public class ShortGuidIdentityGenerator : IIdentityGenerator +{ + /// + public string GenerateId() => ShortGuid.NewGuid().ToString(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/SimpleWorkflowJsonDetector.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/SimpleWorkflowJsonDetector.cs new file mode 100644 index 0000000..6bc16ee --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/SimpleWorkflowJsonDetector.cs @@ -0,0 +1,33 @@ +using System.Text.Json; +using Elsa.Studio.Workflows.Domain.Contracts; +using JetBrains.Annotations; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A service that detects whether a JSON string is a workflow definition using a simple heuristic. +/// +[UsedImplicitly] +public class SimpleWorkflowJsonDetector : IWorkflowJsonDetector +{ + /// + public bool IsWorkflowSchema(string json) + { + var jsonDocument = JsonDocument.Parse(json); + var rootElement = jsonDocument.RootElement; + + if (!rootElement.TryGetProperty("definitionId", out _)) + return false; + + if (!rootElement.TryGetProperty("id", out _)) + return false; + + if (!rootElement.TryGetProperty("root", out _)) + return false; + + if (!rootElement.TryGetProperty("name", out _)) + return false; + + return true; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionEditorService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionEditorService.cs new file mode 100644 index 0000000..cfcf2f9 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionEditorService.cs @@ -0,0 +1,140 @@ +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Responses; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Extensions; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Domain.Notifications; +using Refit; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A workflow definition service that uses a remote backend to retrieve workflow definitions. +/// +public class WorkflowDefinitionEditorService(IBackendApiClientProvider backendApiClientProvider, IMediator mediator) : IWorkflowDefinitionEditorService +{ + /// + public async Task> SaveAsync(WorkflowDefinition workflowDefinition, bool publish, Func? workflowSavedCallback = null, CancellationToken cancellationToken = default) + { + var request = new SaveWorkflowDefinitionRequest + { + Model = new WorkflowDefinitionModel + { + Id = workflowDefinition.Id, + Description = workflowDefinition.Description, + Name = workflowDefinition.Name, + ToolVersion = workflowDefinition.ToolVersion, + Inputs = workflowDefinition.Inputs, + Options = workflowDefinition.Options, + Outcomes = workflowDefinition.Outcomes, + Outputs = workflowDefinition.Outputs, + Variables = workflowDefinition.Variables.Select(x => new VariableDefinition + { + Id = x.Id, + Name = x.Name, + TypeName = x.TypeName, + Value = x.Value?.ToString(), + IsArray = x.IsArray, + StorageDriverTypeName = x.StorageDriverTypeName + }).ToList(), + Version = workflowDefinition.Version, + CreatedAt = workflowDefinition.CreatedAt, + CustomProperties = workflowDefinition.CustomProperties, + DefinitionId = workflowDefinition.DefinitionId, + IsLatest = workflowDefinition.IsLatest, + IsPublished = workflowDefinition.IsPublished, + Root = workflowDefinition.Root + }, + Publish = publish, + }; + + var api = await GetApiAsync(cancellationToken); + + try + { + if (request.Publish == true) await mediator.NotifyAsync(new WorkflowDefinitionPublishing(workflowDefinition), cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionSaving(workflowDefinition), cancellationToken); + var response = await api.SaveAsync(request, cancellationToken); + + if(workflowSavedCallback != null) + await workflowSavedCallback(response.WorkflowDefinition); + + await mediator.NotifyAsync(new WorkflowDefinitionSaved(response.WorkflowDefinition), cancellationToken); + if (request.Publish == true) await mediator.NotifyAsync(new WorkflowDefinitionPublished(response.WorkflowDefinition), cancellationToken); + return new(response); + } + catch (ValidationApiException e) + { + var errors = e.GetValidationErrors(); + await mediator.NotifyAsync(new WorkflowDefinitionSavingFailed(workflowDefinition, errors), cancellationToken); + if (request.Publish == true) await mediator.NotifyAsync(new WorkflowDefinitionPublishingFailed(workflowDefinition, errors), cancellationToken); + return new(errors); + } + } + + /// + public async Task PublishAsync(WorkflowDefinition workflowDefinition, Func? workflowPublishedCallback = null, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionPublishing(workflowDefinition), cancellationToken); + var response = await api.PublishAsync(workflowDefinition.DefinitionId, new PublishWorkflowDefinitionRequest(), cancellationToken); + if(workflowPublishedCallback != null) await workflowPublishedCallback(workflowDefinition); + await mediator.NotifyAsync(new WorkflowDefinitionPublished(workflowDefinition), cancellationToken); + return response; + } + + /// + public async Task> RetractAsync(WorkflowDefinition workflowDefinition, Func? workflowRetractedCallback = null, CancellationToken cancellationToken = default) + { + try + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionRetracting(workflowDefinition), cancellationToken); + var definition = await api.RetractAsync(workflowDefinition.DefinitionId, new RetractWorkflowDefinitionRequest(), cancellationToken); + if(workflowRetractedCallback != null) await workflowRetractedCallback(definition); + await mediator.NotifyAsync(new WorkflowDefinitionRetracted(definition), cancellationToken); + return new(definition); + } + catch (ValidationApiException e) + { + var errors = e.GetValidationErrors(); + await mediator.NotifyAsync(new WorkflowDefinitionRetractingFailed(workflowDefinition, errors), cancellationToken); + return new(errors); + } + } + + /// + public async Task ExportAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionExporting(workflowDefinition), cancellationToken); + var response = await api.ExportAsync(workflowDefinition.DefinitionId, VersionOptions.SpecificVersion(workflowDefinition.Version), cancellationToken); + var fileName = response.GetDownloadedFileNameOrDefault($"workflow-definition-{workflowDefinition.DefinitionId}-v{workflowDefinition.Version}.json"); + var fileDownload = new FileDownload(fileName, response.Content!); + await mediator.NotifyAsync(new WorkflowDefinitionExported(workflowDefinition, fileDownload), cancellationToken); + + return fileDownload; + } + + /// + public async Task RevertAsync(WorkflowDefinitionVersion workflowDefinitionVersion, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionVersionReverting(workflowDefinitionVersion), cancellationToken); + var newWorkflowDefinitionSummary = await api.RevertVersionAsync(workflowDefinitionVersion.WorkflowDefinitionId, workflowDefinitionVersion.Version, cancellationToken); + var newWorkflowDefinitionVersion = WorkflowDefinitionVersion.FromDefinitionSummary(newWorkflowDefinitionSummary); + await mediator.NotifyAsync(new WorkflowDefinitionVersionReverted(newWorkflowDefinitionVersion), cancellationToken); + return newWorkflowDefinitionSummary; + } + + private async Task GetApiAsync(CancellationToken cancellationToken = default) + { + return await backendApiClientProvider.GetApiAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionHistoryService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionHistoryService.cs new file mode 100644 index 0000000..70e53ef --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionHistoryService.cs @@ -0,0 +1,54 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Extensions; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Domain.Notifications; +using Refit; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A workflow definition service that uses a remote backend to retrieve workflow definitions. +/// +public class WorkflowDefinitionHistoryService(IBackendApiClientProvider backendApiClientProvider, IMediator mediator) : IWorkflowDefinitionHistoryService +{ + /// + public async Task> RetractAsync(WorkflowDefinition workflowDefinition, Func? workflowRetractedCallback = null, CancellationToken cancellationToken = default) + { + try + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionRetracting(workflowDefinition), cancellationToken); + var definition = await api.RetractAsync(workflowDefinition.DefinitionId, new RetractWorkflowDefinitionRequest(), cancellationToken); + if(workflowRetractedCallback != null) await workflowRetractedCallback(definition); + await mediator.NotifyAsync(new WorkflowDefinitionRetracted(definition), cancellationToken); + return new(definition); + } + catch (ValidationApiException e) + { + var errors = e.GetValidationErrors(); + await mediator.NotifyAsync(new WorkflowDefinitionRetractingFailed(workflowDefinition, errors), cancellationToken); + return new(errors); + } + } + + /// + public async Task RevertAsync(WorkflowDefinitionVersion workflowDefinitionVersion, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionVersionReverting(workflowDefinitionVersion), cancellationToken); + var newWorkflowDefinitionSummary = await api.RevertVersionAsync(workflowDefinitionVersion.WorkflowDefinitionId, workflowDefinitionVersion.Version, cancellationToken); + var newWorkflowDefinitionVersion = WorkflowDefinitionVersion.FromDefinitionSummary(newWorkflowDefinitionSummary); + await mediator.NotifyAsync(new WorkflowDefinitionVersionReverted(newWorkflowDefinitionVersion), cancellationToken); + return newWorkflowDefinitionSummary; + } + + private async Task GetApiAsync(CancellationToken cancellationToken = default) + { + return await backendApiClientProvider.GetApiAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionImporter.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionImporter.cs new file mode 100644 index 0000000..96cdee0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionImporter.cs @@ -0,0 +1,158 @@ +using System.IO.Compression; +using System.Net.Mime; +using System.Text.Json; +using System.Text.Json.Serialization; +using Elsa.Api.Client.Converters; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Domain.Notifications; +using Microsoft.AspNetCore.Components.Forms; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A workflow definition service that uses a remote backend to retrieve workflow definitions. +/// +public class WorkflowDefinitionImporter(IBackendApiClientProvider backendApiClientProvider, IMediator mediator, IWorkflowJsonDetector workflowJsonDetector) : IWorkflowDefinitionImporter +{ + private async Task GetApiAsync(CancellationToken cancellationToken = default) + { + return await backendApiClientProvider.GetApiAsync(cancellationToken); + } + + /// + public async Task> ImportFilesAsync(IReadOnlyList files, ImportOptions? options = null) + { + var maxAllowedSize = options?.MaxAllowedSize ?? 1024 * 1024 * 10; // 10 MB + var results = new List(); + + foreach (var file in files) + { + await mediator.NotifyAsync(new ImportingFile(file)); + await using var stream = file.OpenReadStream(maxAllowedSize); + + if (file.ContentType == MediaTypeNames.Application.Zip || file.Name.EndsWith(".zip")) + { + var importZipFileResults = await ImportZipFileAsync(stream, options); + results.AddRange(importZipFileResults); + await mediator.NotifyAsync(new ImportedFile(file)); + } + + else if (file.ContentType == MediaTypeNames.Application.Json || file.Name.EndsWith(".json")) + { + var importFromStreamResult = await ImportFromStreamAsync(file.Name, stream, options); + results.Add(importFromStreamResult); + await mediator.NotifyAsync(new ImportedFile(file)); + } + } + + return results; + } + + private async Task> ImportZipFileAsync(Stream stream, ImportOptions? options) + { + using var memoryStream = new MemoryStream(); + await stream.CopyToAsync(memoryStream); + memoryStream.Seek(0, SeekOrigin.Begin); + var importResultList = new List(); + + try + { + var zipArchive = new ZipArchive(memoryStream); + foreach (var entry in zipArchive.Entries.Where(x => !x.FullName.StartsWith("__MACOSX", StringComparison.OrdinalIgnoreCase))) + { + if (entry.FullName.EndsWith(".json")) + { + await using var entryStream = entry.Open(); + var result = await ImportFromStreamAsync(entry.Name, entryStream, options); + + importResultList.Add(result); + } + else if (entry.FullName.EndsWith(".zip")) + { + await using var entryStream = entry.Open(); + var results = await ImportZipFileAsync(entryStream, options); + importResultList.AddRange(results); + } + } + } + catch (Exception e) + { + if (options?.ErrorCallback != null) + await options.ErrorCallback(e); + importResultList.Add(new() + { + Failure = new(e.Message, WorkflowImportFailureType.Exception) + }); + } + + return importResultList; + } + + private async Task ImportFromStreamAsync(string fileName, Stream stream, ImportOptions? options) + { + using var reader = new StreamReader(stream); + var json = await reader.ReadToEndAsync(); + var jsonSerializerOptions = CreateJsonSerializerOptions(); + + try + { + await mediator.NotifyAsync(new ImportingJson(json)); + + if (!workflowJsonDetector.IsWorkflowSchema(json)) + { + return new() + { + FileName = fileName, + Failure = new("Invalid schema", WorkflowImportFailureType.InvalidSchema) + }; + } + + var model = JsonSerializer.Deserialize(json, jsonSerializerOptions)!; + + if (options?.DefinitionId != null) + model.DefinitionId = options.DefinitionId; + + await mediator.NotifyAsync(new ImportingWorkflowDefinition(model)); + var api = await GetApiAsync(); + var newWorkflowDefinition = await api.ImportAsync(model); + + if (options?.ImportedCallback != null) + await options.ImportedCallback(newWorkflowDefinition); + + await mediator.NotifyAsync(new ImportedWorkflowDefinition(newWorkflowDefinition)); + await mediator.NotifyAsync(new ImportedJson(json)); + + return new() + { + FileName = fileName, + WorkflowDefinition = newWorkflowDefinition + }; + } + catch (Exception e) + { + if (options?.ErrorCallback != null) + await options.ErrorCallback(e); + return new() + { + FileName = fileName, + Failure = new(e.Message, WorkflowImportFailureType.Exception) + }; + } + } + + private static JsonSerializerOptions CreateJsonSerializerOptions() + { + JsonSerializerOptions options = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + options.Converters.Add(new JsonStringEnumConverter()); + options.Converters.Add(new VersionOptionsJsonConverter()); + return options; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionService.cs b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionService.cs new file mode 100644 index 0000000..f3139a6 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Domain/Services/WorkflowDefinitionService.cs @@ -0,0 +1,293 @@ +using System.Net; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Responses; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Extensions; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Domain.Notifications; +using Refit; + +namespace Elsa.Studio.Workflows.Domain.Services; + +/// +/// A workflow definition service that uses a remote backend to retrieve workflow definitions. +/// +public class RemoteWorkflowDefinitionService(IBackendApiClientProvider backendApiClientProvider, IIdentityGenerator identityGenerator, IMediator mediator) : IWorkflowDefinitionService +{ + /// + public async Task> ListAsync(ListWorkflowDefinitionsRequest request, VersionOptions? versionOptions = null, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + return await api.ListAsync(request, versionOptions, cancellationToken); + } + + /// + public async Task FindByDefinitionIdAsync(string definitionId, VersionOptions? versionOptions = null, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + return await api.GetByDefinitionIdAsync(definitionId, versionOptions, cancellationToken); + } + + /// + public async Task FindByIdAsync(string id, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + return await api.GetByIdAsync(id, cancellationToken); + } + + /// + public async Task> FindManyByIdAsync(IEnumerable ids, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + var response = await api.GetManyByIdAsync(ids.ToList(), cancellationToken); + return response.Items; + } + + /// + public async Task FindSubgraphAsync(string id, string? parentNodeId = null, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + return await api.GetSubgraphAsync(id, parentNodeId, cancellationToken); + } + + /// + public async Task GetPathSegmentsAsync(string id, string? childNodeId = null, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + return await api.GetPathSegmentsGetAsync(id, childNodeId, cancellationToken); + } + + /// + public async Task PublishAsync(string definitionId, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionIdPublishing(definitionId), cancellationToken); + var response = await api.PublishAsync(definitionId, new PublishWorkflowDefinitionRequest(), cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionPublished(response.WorkflowDefinition), cancellationToken); + return response; + } + + /// + public async Task> RetractAsync(string definitionId, CancellationToken cancellationToken = default) + { + try + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionIdRetracting(definitionId), cancellationToken); + var definition = await api.RetractAsync(definitionId, new RetractWorkflowDefinitionRequest(), cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionRetracted(definition), cancellationToken); + return new(definition); + } + catch (ValidationApiException e) + { + var errors = e.GetValidationErrors(); + await mediator.NotifyAsync(new WorkflowDefinitionIdRetractingFailed(definitionId, errors), cancellationToken); + return new(errors); + } + } + + /// + public async Task DeleteAsync(string definitionId, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + + try + { + await mediator.NotifyAsync(new WorkflowDefinitionDeleting(definitionId), cancellationToken); + await api.DeleteAsync(definitionId, cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionDeleted(definitionId), cancellationToken); + return true; + } + catch (ApiException e) when (e.StatusCode == HttpStatusCode.NotFound) + { + return false; + } + } + + /// + public async Task DeleteVersionAsync(WorkflowDefinitionVersion workflowDefinitionVersion, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + + try + { + await mediator.NotifyAsync(new WorkflowDefinitionVersionDeleting(workflowDefinitionVersion), cancellationToken); + await api.DeleteVersionAsync(workflowDefinitionVersion.WorkflowDefinitionVersionId, cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionVersionDeleted(workflowDefinitionVersion), cancellationToken); + return true; + } + catch (ApiException e) when (e.StatusCode == HttpStatusCode.NotFound) + { + return false; + } + } + + /// + public async Task BulkDeleteAsync(IEnumerable definitionIds, CancellationToken cancellationToken = default) + { + var definitionIdList = definitionIds.ToList(); + await mediator.NotifyAsync(new BulkWorkflowDefinitionsDeleting(definitionIdList), cancellationToken); + var request = new BulkDeleteWorkflowDefinitionsRequest(definitionIdList); + var api = await GetApiAsync(cancellationToken); + var response = await api.BulkDeleteAsync(request, cancellationToken); + await mediator.NotifyAsync(new BulkWorkflowDefinitionsDeleted(definitionIdList), cancellationToken); + return response.Deleted; + } + + /// + public async Task BulkDeleteVersionsAsync(IEnumerable workflowDefinitionVersions, CancellationToken cancellationToken = default) + { + var versions = workflowDefinitionVersions.ToList(); + var ids = versions.Select(x => x.WorkflowDefinitionVersionId).ToList(); + await mediator.NotifyAsync(new BulkWorkflowDefinitionVersionsDeleting(versions), cancellationToken); + var request = new BulkDeleteWorkflowDefinitionVersionsRequest(ids); + var api = await GetApiAsync(cancellationToken); + var response = await api.BulkDeleteVersionsAsync(request, cancellationToken); + await mediator.NotifyAsync(new BulkWorkflowDefinitionVersionsDeleted(versions), cancellationToken); + return response.Deleted; + } + + /// + public async Task BulkPublishAsync(IEnumerable definitionIds, CancellationToken cancellationToken = default) + { + var request = new BulkPublishWorkflowDefinitionsRequest(definitionIds); + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new BulkWorkflowDefinitionsPublishing(request.DefinitionIds), cancellationToken); + var response = await api.BulkPublishAsync(request, cancellationToken); + await mediator.NotifyAsync(new BulkWorkflowDefinitionsPublished(response.Published), cancellationToken); + return response; + } + + /// + public async Task BulkRetractAsync(IEnumerable definitionIds, CancellationToken cancellationToken = default) + { + var definitionIdList = definitionIds.ToList(); + await mediator.NotifyAsync(new BulkWorkflowDefinitionsRetracting(definitionIdList), cancellationToken); + var request = new BulkRetractWorkflowDefinitionsRequest(definitionIdList); + var api = await GetApiAsync(cancellationToken); + var response = await api.BulkRetractAsync(request, cancellationToken); + await mediator.NotifyAsync(new BulkWorkflowDefinitionsRetracted(response.Retracted), cancellationToken); + return response; + } + + /// + public async Task GetIsNameUniqueAsync(string name, string? definitionId = null, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + var response = await api.GetIsNameUniqueAsync(name, definitionId, cancellationToken); + + return response.IsUnique; + } + + /// + public async Task GenerateUniqueNameAsync(CancellationToken cancellationToken = default) + { + const int maxAttempts = 100; + var attempt = 0; + + while (attempt < maxAttempts) + { + var name = $"Workflow {++attempt}"; + var isUnique = await GetIsNameUniqueAsync(name, null, cancellationToken); + + if (isUnique) + return name; + } + + throw new Exception($"Failed to generate a unique workflow name after {maxAttempts} attempts."); + } + + /// + public async Task> CreateNewDefinitionAsync(string name, string? description = null, CancellationToken cancellationToken = default) + { + var saveRequest = new SaveWorkflowDefinitionRequest + { + Model = new WorkflowDefinitionModel + { + Name = name, + Description = description, + Version = 1, + ToolVersion = ToolVersion.Version, + IsLatest = true, + IsPublished = false, + Root = new JsonObject(new Dictionary + { + ["id"] = identityGenerator.GenerateId(), + ["type"] = "Elsa.Flowchart", + ["version"] = 1, + ["name"] = "Flowchart1" + }) + } + }; + + var api = await GetApiAsync(cancellationToken); + + try + { + var response = await api.SaveAsync(saveRequest, cancellationToken); + return new Result(response.WorkflowDefinition); + } + catch (ValidationApiException e) + { + var errors = e.GetValidationErrors(); + return new Result(errors); + } + } + + /// + public async Task ExportDefinitionAsync(string definitionId, VersionOptions? versionOptions = null, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + await mediator.NotifyAsync(new WorkflowDefinitionIdExporting(definitionId, versionOptions), cancellationToken); + var response = await api.ExportAsync(definitionId, versionOptions, cancellationToken); + var fileName = response.GetDownloadedFileNameOrDefault($"workflow-definition-{definitionId}.json"); + var fileDownload = new FileDownload(fileName, response.Content!); + await mediator.NotifyAsync(new WorkflowDefinitionIdExported(definitionId, versionOptions, fileDownload), cancellationToken); + + return fileDownload; + } + + /// + public async Task BulkExportDefinitionsAsync(IEnumerable ids, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + var request = new BulkExportWorkflowDefinitionsRequest(ids.ToArray()); + var response = await api.BulkExportAsync(request, cancellationToken); + var fileName = response.GetDownloadedFileNameOrDefault("workflow-definitions.zip"); + return new FileDownload(fileName, response.Content!); + } + + /// + public async Task UpdateReferencesAsync(string definitionId, CancellationToken cancellationToken = default) + { + var api = await GetApiAsync(cancellationToken); + return await api.UpdateReferencesAsync(definitionId, new UpdateConsumingWorkflowReferencesRequest(), cancellationToken); + } + + /// + public async Task ExecuteAsync(string definitionId, ExecuteWorkflowDefinitionRequest? request, CancellationToken cancellationToken = default) + { + var api = await GetExecuteWorkflowApiAsync(cancellationToken); + var response = await api.ExecuteAsync(definitionId, request, cancellationToken); + var workflowInstanceId = response.Headers.TryGetValues("x-elsa-workflow-instance-id", out var workflowInstanceIdValues) ? workflowInstanceIdValues.FirstOrDefault() : null; + var cannotStart = string.Equals(response.Headers.TryGetValues("x-elsa-workflow-cannot-start", out var cannotStartValues) ? cannotStartValues.FirstOrDefault() : null, "true", StringComparison.OrdinalIgnoreCase); + return new ExecuteWorkflowResult(workflowInstanceId, cannotStart); + } + + private async Task GetApiAsync(CancellationToken cancellationToken = default) + { + return await backendApiClientProvider.GetApiAsync(cancellationToken); + } + + private async Task GetExecuteWorkflowApiAsync(CancellationToken cancellationToken = default) + { + return await backendApiClientProvider.GetApiAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Elsa.Studio.Workflows.Core.csproj b/src/modules/Elsa.Studio.Workflows.Core/Elsa.Studio.Workflows.Core.csproj new file mode 100644 index 0000000..a079001 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Elsa.Studio.Workflows.Core.csproj @@ -0,0 +1,22 @@ + + + + Elsa Studio workflows core services. + elsa studio core + Elsa.Studio.Workflows + + + + + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Workflows.Core/Extensions/ActivityExtensions.cs b/src/modules/Elsa.Studio.Workflows.Core/Extensions/ActivityExtensions.cs new file mode 100644 index 0000000..f31fa48 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Extensions/ActivityExtensions.cs @@ -0,0 +1,29 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; + +namespace Elsa.Studio.Workflows.Extensions; + +/// +/// Provides extension methods for representing an activity +/// +public static class ActivityExtensions +{ + /// + /// Gets the flowchart from the specified activity. + /// + /// + /// + /// + public static JsonObject GetFlowchart(this JsonObject activity) + { + var activityTypeName = activity.GetTypeName(); + + if (activityTypeName == "Elsa.Flowchart") + return activity; + + if (activityTypeName == "Elsa.Workflow") + return activity.GetRoot()!; + + throw new NotSupportedException(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Extensions/ActivityVisitorExtensions.cs b/src/modules/Elsa.Studio.Workflows.Core/Extensions/ActivityVisitorExtensions.cs new file mode 100644 index 0000000..b4d5442 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Extensions/ActivityVisitorExtensions.cs @@ -0,0 +1,62 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Extensions; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Extensions; + +/// A set of extensions for . +public static class ActivityVisitorExtensions +{ + /// Returns a lookup dictionary by activity ID. + public static async Task> VisitAndMapAsync(this IActivityVisitor visitor, WorkflowDefinition workflowDefinition) + { + var workflowActivity = ToActivity(workflowDefinition); + return await visitor.VisitAndMapAsync(workflowActivity); + } + + /// Returns a lookup dictionary by activity ID. + public static async Task VisitAsync(this IActivityVisitor visitor, WorkflowDefinition workflowDefinition) + { + var workflowActivity = ToActivity(workflowDefinition); + return await visitor.VisitAsync(workflowActivity); + } + + /// Returns a lookup dictionary by activity ID. + public static async Task> VisitAndMapAsync(this IActivityVisitor visitor, JsonObject activity) + { + var graph = await visitor.VisitAsync(activity); + var nodes = graph.Flatten(); + return nodes.ToDictionary(x => x.NodeId); + } + + /// Creates an activity graph based on the provided workflow definition. + public static async Task VisitAndCreateGraphAsync(this IActivityVisitor visitor, WorkflowDefinition workflowDefinition) + { + var workflowActivity = ToActivity(workflowDefinition); + return await visitor.VisitAndCreateGraphAsync(workflowActivity); + } + + /// Creates an activity graph based on the provided JSON activity. + public static async Task VisitAndCreateGraphAsync(this IActivityVisitor visitor, JsonObject activity) + { + return await new ActivityGraph(activity, visitor).IndexAsync(); + } + + /// Creates an activity from the specified workflow definition. + private static JsonObject ToActivity(WorkflowDefinition workflowDefinition) + { + var workflowActivity = new JsonObject(); + workflowActivity.SetId("Workflow1"); + workflowActivity.SetNodeId("Workflow1"); + workflowActivity.SetTypeName("Elsa.Workflow"); + workflowActivity.SetVersion(1); + workflowActivity.SetName(workflowDefinition.Name); + workflowActivity.SetRoot(workflowDefinition.Root); + return workflowActivity; + } + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Workflows.Core/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..f274b44 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,85 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Services; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Providers; +using Elsa.Studio.Workflows.Domain.Services; +using Elsa.Studio.Workflows.Resolvers; +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.UI.Providers; +using Elsa.Studio.Workflows.UI.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Workflows.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the workflows module. + /// + public static IServiceCollection AddWorkflowsCore(this IServiceCollection services) + { + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + ; + + services.AddActivityDisplaySettingsProvider(); + services.AddActivityPortProvider(); + + return services; + } + + /// + /// Adds a to the service collection. + /// + public static IServiceCollection AddDiagramDesignerProvider(this IServiceCollection services) where T : class, IDiagramDesignerProvider + { + services.AddScoped(); + return services; + } + + /// + /// Adds a to the service collection. + /// + public static IServiceCollection AddActivityDisplaySettingsProvider(this IServiceCollection services) where T : class, IActivityDisplaySettingsProvider + { + services.AddScoped(); + return services; + } + + /// + /// Adds a to the service collection. + /// + public static IServiceCollection AddActivityPortProvider(this IServiceCollection services) where T : class, IActivityPortProvider + { + services.AddScoped(); + return services; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/FodyWeavers.xml b/src/modules/Elsa.Studio.Workflows.Core/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/FodyWeavers.xsd b/src/modules/Elsa.Studio.Workflows.Core/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/Resolvers/DefaultActivityResolver.cs b/src/modules/Elsa.Studio.Workflows.Core/Resolvers/DefaultActivityResolver.cs new file mode 100644 index 0000000..2cbb070 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/Resolvers/DefaultActivityResolver.cs @@ -0,0 +1,33 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; + +namespace Elsa.Studio.Workflows.Resolvers; + +/// +/// A default resolver. +/// +public class DefaultActivityResolver : IActivityResolver +{ + /// + public int Priority => -1; + + /// + public bool GetSupportsActivity(JsonObject activity) => true; + + /// + public ValueTask> GetActivitiesAsync(JsonObject activity, CancellationToken cancellationToken = default) + { + var containedActivities = + from prop in activity + where prop.Value is JsonObject jsonObject && jsonObject.IsActivity() || prop.Value is JsonArray + let isCollection = prop.Value is JsonArray + let containedItems = isCollection ? ((JsonArray)prop.Value).ToArray() : new[] { prop.Value.AsObject() } + from containedItem in containedItems where containedItem is JsonObject && containedItem.AsObject().IsActivity() + let containedObject = containedItem.AsObject() + select new EmbeddedActivity(containedObject, prop.Key); + + return new(containedActivities.ToList()); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Args/ActivityEmbeddedPortSelectedArgs.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Args/ActivityEmbeddedPortSelectedArgs.cs new file mode 100644 index 0000000..38286bf --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Args/ActivityEmbeddedPortSelectedArgs.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Workflows.UI.Args; + +/// +/// Represents the arguments for the ActivityEmbeddedPortSelected event. +/// +/// The activity that contains the port. +/// The name of the port. +public record ActivityEmbeddedPortSelectedArgs(JsonObject Activity, string PortName); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contexts/DisplayContext.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contexts/DisplayContext.cs new file mode 100644 index 0000000..1688c03 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contexts/DisplayContext.cs @@ -0,0 +1,26 @@ +using System.Text.Json.Nodes; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Args; +using Elsa.Studio.Workflows.UI.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.UI.Contexts; + +/// +/// Represents a context for displaying an activity. +/// +/// The activity to display. +/// A callback that is invoked when an activity is selected. +/// A callback that is invoked when an embedded port is selected. +/// A callback that is invoked when the graph is updated. +/// Whether the activity is read-only. +/// A map of activity stats. +public record DisplayContext( + JsonObject Activity, + EventCallback ActivitySelectedCallback = default, + EventCallback ActivityUpdated = default, + EventCallback ActivityEmbeddedPortSelectedCallback = default, + EventCallback ActivityDoubleClickCallback = default, + EventCallback GraphUpdatedCallback = default, + bool IsReadOnly = false, + IDictionary? ActivityStats = null); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IActivityDisplaySettingsProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IActivityDisplaySettingsProvider.cs new file mode 100644 index 0000000..f2d9eab --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IActivityDisplaySettingsProvider.cs @@ -0,0 +1,17 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.UI.Contracts; + +/// +/// Provides mappings between activity types and icons. +/// +public interface IActivityDisplaySettingsProvider +{ + /// + /// Returns a dictionary of activity type to display settings. + /// + /// + /// + IDictionary GetSettings(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IActivityDisplaySettingsRegistry.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IActivityDisplaySettingsRegistry.cs new file mode 100644 index 0000000..738b836 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IActivityDisplaySettingsRegistry.cs @@ -0,0 +1,21 @@ +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.UI.Contracts; + +/// +/// Provides mappings between activity types and icons. +/// +public interface IActivityDisplaySettingsRegistry +{ + /// + /// Retrieves the display settings for the specified activity type. + /// + /// The activity type. + /// The display settings for the specified activity type. + ActivityDisplaySettings GetSettings(string activityType); + + /// + /// Marks the activity display settings registry as stale. + /// + void MarkStale(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesigner.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesigner.cs new file mode 100644 index 0000000..e77f26f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesigner.cs @@ -0,0 +1,50 @@ +using System.Text.Json.Nodes; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Contexts; +using Elsa.Studio.Workflows.UI.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.UI.Contracts; + +/// +/// Represents a diagram editor. +/// +public interface IDiagramDesigner +{ + /// + /// Loads the specified root activity int the designer. + /// + /// The root activity to load. + /// A map of activity stats. + Task LoadRootActivityAsync(JsonObject activity, IDictionary? activityStatsMap); + + /// + /// Updates the specified activity in the diagram. This is used to update the diagram when an activity is updated in the activity editor. + /// + /// The ID of the activity to update. + /// The activity to update. + Task UpdateActivityAsync(string id, JsonObject activity); + + /// + /// Updates the stats of the specified activity. + /// + /// The ID of the activity to update. + /// The stats to update. + Task UpdateActivityStatsAsync(string id, ActivityStats stats); + + /// + /// Selects the specified activity in the diagram. + /// + /// The ID of the activity to select. + Task SelectActivityAsync(string id); + + /// + /// Reads the root activity from the diagram. + /// + Task ReadRootActivityAsync(); + + /// + /// Display the designer. + /// + RenderFragment DisplayDesigner(DisplayContext context); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerProvider.cs new file mode 100644 index 0000000..0dce249 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerProvider.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Workflows.UI.Contracts; + +/// +/// Implement this interface to provide a diagram editor for a given workflow definition's root activity. +/// +public interface IDiagramDesignerProvider +{ + double Priority { get; } + bool GetSupportsActivity(JsonObject activity); + IDiagramDesigner GetEditor(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerService.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerService.cs new file mode 100644 index 0000000..49d41cb --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerService.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Workflows.UI.Contracts; + +/// +/// A service for managing diagram editors. +/// +public interface IDiagramDesignerService +{ + /// + /// Gets the diagram designer for the specified activity. + /// + IDiagramDesigner GetDiagramDesigner(JsonObject activity); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerToolboxProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerToolboxProvider.cs new file mode 100644 index 0000000..add5672 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesignerToolboxProvider.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.UI.Contracts; + +/// +/// Implement this interface to provide toolbox items for the diagram editor. +/// +public interface IDiagramDesignerToolboxProvider : IDiagramDesigner +{ + IEnumerable GetToolboxItems(bool isReadOnly); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IWorkspace.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IWorkspace.cs new file mode 100644 index 0000000..39bcc99 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IWorkspace.cs @@ -0,0 +1,17 @@ +namespace Elsa.Studio.Workflows.UI.Contracts; + +/// +/// Represents a workspace. +/// +public interface IWorkspace +{ + /// + /// Gets a value indicating whether the workspace is read-only. + /// + bool IsReadOnly { get; } + + /// + /// Geta a value indicating whether the user has permissions to edit the workflow. + /// + bool HasWorkflowEditPermission { get; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Models/ActivityDisplaySettings.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Models/ActivityDisplaySettings.cs new file mode 100644 index 0000000..2452d7f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Models/ActivityDisplaySettings.cs @@ -0,0 +1,33 @@ +namespace Elsa.Studio.Workflows.UI.Models; + +/// +/// Represents display settings for an activity. +/// +public class ActivityDisplaySettings +{ + /// + /// Initializes a new instance of the class. + /// + public ActivityDisplaySettings() + { + } + + /// + /// Initializes a new instance of the class. + /// + public ActivityDisplaySettings(string color, string? icon = default) + { + Color = color; + Icon = icon; + } + + /// + /// Gets or sets the icon. + /// + public string? Icon { get; set; } + + /// + /// Gets or sets the color. + /// + public string Color { get; set; } = default!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Models/DefaultActivityColors.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Models/DefaultActivityColors.cs new file mode 100644 index 0000000..c1e970a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Models/DefaultActivityColors.cs @@ -0,0 +1,20 @@ +namespace Elsa.Studio.Workflows.UI.Models; + +/// +/// A static class with default activity colors. +/// +public static class DefaultActivityColors +{ + public static string Default { get; set; } = "var(--mud-palette-primary)"; + public static string NotFound { get; set; } = "var(--mud-palette-error)"; + public static string Composition { get; set; } = "#f97316"; + public static string Console { get; set; } = "#0369a1"; + public static string Http { get; set; } = "#2dd4bf"; + public static string Scripting { get; set; } = "#22c55e"; + public static string Flowchart { get; set; } = "#06b6d4"; + public static string Looping { get; set; } = "#6366f1"; + public static string Primitives { get; set; } = Default; + public static string Email { get; set; } = "#fcd34d"; + public static string Branching { get; set; } = "#06b6d4"; + public static string Timer { get; set; } = "#d946ef"; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Providers/DefaultActivityDisplaySettingsProvider.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Providers/DefaultActivityDisplaySettingsProvider.cs new file mode 100644 index 0000000..5249b5d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Providers/DefaultActivityDisplaySettingsProvider.cs @@ -0,0 +1,86 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.UI.Models; +using JetBrains.Annotations; +using MudBlazor; + +namespace Elsa.Studio.Workflows.UI.Providers; + +/// Provides default activity display settings. +[UsedImplicitly] +public class DefaultActivityDisplaySettingsProvider : IActivityDisplaySettingsProvider +{ + /// + /// + public IDictionary GetSettings() => new Dictionary + { + // Not Found Activity + ["Elsa.NotFoundActivity"] = new(DefaultActivityColors.NotFound, ElsaStudioIcons.Heroicons.Exclamation), + + // Branching + ["Elsa.If"] = new(DefaultActivityColors.Branching, ElsaStudioIcons.Heroicons.Question), + ["Elsa.FlowDecision"] = new(DefaultActivityColors.Branching, ElsaStudioIcons.Heroicons.Question), + ["Elsa.Switch"] = new(DefaultActivityColors.Branching, ElsaStudioIcons.Tabler.SwitchDiagonal), + ["Elsa.FlowSwitch"] = new(DefaultActivityColors.Branching, ElsaStudioIcons.Tabler.SwitchDiagonal), + ["Elsa.FlowJoin"] = new(DefaultActivityColors.Branching, ElsaStudioIcons.Tabler.GitMerge), + ["Elsa.FlowFork"] = new(DefaultActivityColors.Branching, ElsaStudioIcons.Tabler.GitFork), + + // Composition + ["Elsa.Complete"] = new(DefaultActivityColors.Composition, ElsaStudioIcons.Tabler.CheckCircle), + ["Elsa.SetOutput"] = new (DefaultActivityColors.Composition), + ["Elsa.DispatchWorkflow"] = new (DefaultActivityColors.Composition), + ["Elsa.BulkDispatchWorkflows"] = new (DefaultActivityColors.Composition), + ["Elsa.ExecuteWorkflow"] = new (DefaultActivityColors.Composition), + + // Console + ["Elsa.WriteLine"] = new(DefaultActivityColors.Console, ElsaStudioIcons.Tabler.Pencil), + ["Elsa.ReadLine"] = new(DefaultActivityColors.Console, ElsaStudioIcons.Tabler.Text), + + // Email + ["Elsa.SendEmail"] = new(DefaultActivityColors.Email, Icons.Material.Outlined.Email), + + // Flowchart + ["Elsa.Flowchart"] = new(DefaultActivityColors.Flowchart, ElsaStudioIcons.Tabler.GitFork), + ["Elsa.FlowNode"] = new(DefaultActivityColors.Flowchart, ElsaStudioIcons.Tabler.Hexagon), + ["Elsa.Start"] = new(DefaultActivityColors.Flowchart, Icons.Material.Outlined.Start), + ["Elsa.End"] = new(DefaultActivityColors.Flowchart, Icons.Material.Outlined.OutlinedFlag), + + // HTTP + ["Elsa.HttpEndpoint"] = new(DefaultActivityColors.Http, ElsaStudioIcons.Tabler.Cloud), + ["Elsa.WriteHttpResponse"] = new(DefaultActivityColors.Http, ElsaStudioIcons.Heroicons.PencilPaper), + ["Elsa.WriteFileHttpResponse"] = new(DefaultActivityColors.Http, Icons.Material.Outlined.FileDownload), + ["Elsa.SendHttpRequest"] = new(DefaultActivityColors.Http, ElsaStudioIcons.Tabler.World), + ["Elsa.FlowSendHttpRequest"] = new(DefaultActivityColors.Http, ElsaStudioIcons.Tabler.World), + ["Elsa.DownloadHttpFile"] = new(DefaultActivityColors.Http, @Icons.Material.Outlined.CloudDownload), + + // Looping + ["Elsa.While"] = new(DefaultActivityColors.Looping, ElsaStudioIcons.Tabler.RepeatOne), + ["Elsa.ForEach"] = new(DefaultActivityColors.Looping, ElsaStudioIcons.Tabler.RepeatOne), + ["Elsa.For"] = new(DefaultActivityColors.Looping, ElsaStudioIcons.Tabler.RepeatOne), + ["Elsa.ParallelForEach"] = new(DefaultActivityColors.Looping, ElsaStudioIcons.Tabler.RepeatOne), + ["Elsa.Break"] = new(DefaultActivityColors.Looping, ElsaStudioIcons.Tabler.Back1), + + // Primitives + ["Elsa.SetVariable"] = new(DefaultActivityColors.Primitives, ElsaStudioIcons.Tabler.Pencil), + ["Elsa.SetName"] = new(DefaultActivityColors.Primitives, ElsaStudioIcons.Tabler.Italic), + ["Elsa.Finish"] = new(DefaultActivityColors.Primitives, ElsaStudioIcons.Tabler.CheckShield), + ["Elsa.Fault"] = new(DefaultActivityColors.Primitives, Icons.Material.Outlined.ErrorOutline), + ["Elsa.Correlate"] = new(DefaultActivityColors.Primitives, Icons.Material.Outlined.DatasetLinked), + ["Elsa.RunTask"] = new(DefaultActivityColors.Primitives, Icons.Material.Outlined.Settings), + ["Elsa.PublishEvent"] = new(DefaultActivityColors.Primitives, Icons.Material.Outlined.FlashOn), + ["Elsa.Event"] = new(DefaultActivityColors.Primitives, Icons.Material.Outlined.FlashOn), + + // Timers + ["Elsa.Timer"] = new(DefaultActivityColors.Timer, Icons.Material.Outlined.Timer), + ["Elsa.Cron"] = new(DefaultActivityColors.Timer, Icons.Material.Outlined.Timer), + ["Elsa.Delay"] = new(DefaultActivityColors.Timer, Icons.Material.Outlined.RotateLeft), + ["Elsa.StartAt"] = new(DefaultActivityColors.Timer, Icons.Material.Outlined.CalendarMonth), + + // Scripting + ["Elsa.RunJavaScript"] = new(DefaultActivityColors.Scripting, Icons.Material.Outlined.Javascript), + + // Azure Service Bus + ["Elsa.AzureServiceBus.MessageReceived"] = new("#a21caf", ElsaStudioIcons.Heroicons.Incoming), + ["Elsa.AzureServiceBus.SendMessage"] = new("#a21caf", ElsaStudioIcons.Heroicons.Outgoing), + }; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Services/DefaultDiagramDesignerService.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Services/DefaultDiagramDesignerService.cs new file mode 100644 index 0000000..cb77a80 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Services/DefaultDiagramDesignerService.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Studio.Workflows.UI.Contracts; + +namespace Elsa.Studio.Workflows.UI.Services; + +/// +public class DefaultDiagramDesignerService : IDiagramDesignerService +{ + private readonly IEnumerable _providers; + + /// + /// Initializes a new instance of the class. + /// + public DefaultDiagramDesignerService(IEnumerable providers) + { + _providers = providers; + } + + /// + public IDiagramDesigner GetDiagramDesigner(JsonObject activity) + { + var provider = _providers + .OrderByDescending(x => x.Priority) + .FirstOrDefault(x => x.GetSupportsActivity(activity)) ?? throw new Exception($"No diagram editor provider found for activity {activity.GetTypeName()}."); + return provider.GetEditor(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/css/designer.v1.css b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/css/designer.v1.css new file mode 100644 index 0000000..feb8cfb --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/css/designer.v1.css @@ -0,0 +1,26 @@ +.elsa-flowchart-diagram-designer-v1 .x6-graph-background { + background-color: var(--mud-palette-background); +} + +.elsa-flowchart-diagram-designer-v1 .x6-widget-selection-box { + border: 2px dashed var(--mud-palette-secondary); +} + +.elsa-flowchart-diagram-designer-v1 .x6-widget-selection-inner { + border: 1px solid var(--mud-palette-secondary); +} + +.elsa-flowchart-diagram-designer-v1 .elsa-snapline .x6-widget-snapline-horizontal, +.elsa-flowchart-diagram-designer-v1 .elsa-snapline .x6-widget-snapline-vertical { + stroke: var(--mud-palette-secondary); +} + +.elsa-flowchart-diagram-designer-v1 .elsa-activity { + border-left: solid 6px var(--mud-palette-info); + filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); + height: 100%; +} + +.elsa-flowchart-diagram-designer-v1 .elsa-activity-wrapper-badge.has-retries .mud-badge-wrapper .mud-badge { + background-color: #FFEB3B !important; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/css/designer.v2.css b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/css/designer.v2.css new file mode 100644 index 0000000..fd2f09a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/css/designer.v2.css @@ -0,0 +1,101 @@ +.elsa-flowchart-diagram-designer-v2 .x6-graph-background { + background-color: var(--mud-palette-surface); +} + +.elsa-flowchart-diagram-designer-v2 .x6-widget-selection-box { + border: dashed 2px var(--mud-palette-gray-light); + box-shadow: none; +} + +.elsa-flowchart-diagram-designer-v2 .x6-widget-selection-inner { + border: dashed 2px var(--mud-palette-gray-light); + box-shadow: none; +} + +.elsa-flowchart-diagram-designer-v2 .x6-widget-transform { + border: none; +} + +.elsa-flowchart-diagram-designer-v2 .elsa-snapline .x6-widget-snapline-horizontal, +.elsa-flowchart-diagram-designer-v2 .elsa-snapline .x6-widget-snapline-vertical { + stroke: var(--mud-palette-secondary); +} + +.elsa-flowchart-diagram-designer-v2 .elsa-activity-wrapper-badge { + +} + +.elsa-flowchart-diagram-designer-v2 .elsa-activity-wrapper-badge.has-retries .mud-badge-wrapper .mud-badge { + background-color: #FFEB3B !important; +} + +.elsa-flowchart-diagram-designer-v2 .elsa-activity { + height: 100%; +} + +/* Use equal 16px padding all around */ +.elsa-flowchart-diagram-designer-v2 .activity-grid { + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + column-gap: 12px; + padding: 16px; /* top/right/bottom/left = 16px */ + border-radius: 8px; +} + +/* Icon container */ +.elsa-flowchart-diagram-designer-v2 .activity-icon { + background-color: #1976d2; + width: 42px; + height: 42px; + min-width: 42px; /* enforce at least 42px */ + min-height: 42px; + flex: none; /* don’t let flex or grid shrink it */ + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; +} + +/* Middle content (label, type, ports, description) */ +.elsa-flowchart-diagram-designer-v2 .activity-content { + display: flex; + flex-direction: column; + justify-content: center; +} + +/* First line: activity label stays default color */ +.elsa-flowchart-diagram-designer-v2 .activity-label { + white-space: nowrap; +} + +/* Second line: lighter grey to mimic original */ +.elsa-flowchart-diagram-designer-v2 .activity-type { + color: var(--mud-palette-gray-light); + font-size: 0.75rem; /* slightly smaller */ + white-space: nowrap; +} + +/* Embedded ports row */ +.elsa-flowchart-diagram-designer-v2 .activity-ports { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 4px; +} + +.elsa-flowchart-diagram-designer-v2 .activity-ports .mud-input.mud-input-outlined .mud-input-outlined-border { + border-style: dashed !important; +} + +/* Optional description below */ +.elsa-flowchart-diagram-designer-v2 .activity-description { + margin-top: 4px; + font-size: 0.75rem; + color: #666; +} + +/* Menu on the right: vertically center */ +.elsa-flowchart-diagram-designer-v2 .activity-menu { + align-self: center; +} diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/package.json b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/package.json new file mode 100644 index 0000000..1003231 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/package.json @@ -0,0 +1,32 @@ +{ + "name": "elsa-designer-dependencies", + "description": "Bundle dependencies for the designer.", + "repository": "https://github.com/elsa-workflows/elsa-dashboard", + "license": "MIT", + "version": "1.0.0", + "dependencies": { + "@antv/layout": "^0.3.25", + "@antv/x6": "^2.18.1", + "@antv/x6-plugin-clipboard": "^2.1.6", + "@antv/x6-plugin-history": "^2.2.4", + "@antv/x6-plugin-keyboard": "^2.2.3", + "@antv/x6-plugin-scroller": "^2.0.10", + "@antv/x6-plugin-selection": "^2.2.2", + "@antv/x6-plugin-snapline": "^2.1.7", + "@antv/x6-plugin-transform": "^2.1.8", + "lodash.camelcase": "^4.3.0", + "uuid": "^10.0.0" + }, + "devDependencies": { + "copy-webpack-plugin": "^13.0.0", + "css-loader": "^7.1.2", + "style-loader": "^4.0.0", + "ts-loader": "^9.5.1", + "typescript": "^5.3.3", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4" + }, + "scripts": { + "build": "webpack" + } +} diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer.ts new file mode 100644 index 0000000..5f8eb1d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer.ts @@ -0,0 +1,7 @@ +import "../css/designer.v1.css"; +import "../css/designer.v2.css"; +import {initialize} from "./designer/internal/init"; + +export * from "./designer/api"; + +initialize(); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/add-activity-node.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/add-activity-node.ts new file mode 100644 index 0000000..887e2cf --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/add-activity-node.ts @@ -0,0 +1,19 @@ +import {Node} from "@antv/x6"; +import {graphBindings} from "./graph-bindings"; + +export async function addActivityNode(graphId: string, node: Node.Properties) { + // Get graph reference. + const {graph} = graphBindings[graphId]; + + // Convert the node coordinates from page to local. + const {x, y} = graph.pageToLocal(node.position); + + node.position = {x, y}; + node.size = {width: 200, height: 50}; + node.id = node.id!; + + // Add the node to the graph. + graph.addNode(node); + graph.cleanSelection(); + graph.select(node.id); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/auto-layout.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/auto-layout.ts new file mode 100644 index 0000000..0700726 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/auto-layout.ts @@ -0,0 +1,21 @@ +import {Model} from '@antv/x6'; +import {DagreLayout} from '@antv/layout'; +import {loadGraph} from './load-graph'; +import {graphBindings} from './graph-bindings'; + +const dagreLayout = new DagreLayout({ + type: 'dagre', + rankdir: 'LR', + align: 'DL', + ranksep: 35, + nodesep: 15, +}) + +export async function autoLayout(graphId: string, data: string | Model.FromJSONData) { + const {graph, interop} = graphBindings[graphId]; + const model = typeof data === 'string' ? JSON.parse(data) : data; + const newModel = dagreLayout.layout(model); + + loadGraph(graphId, newModel); + await interop.raiseGraphUpdated(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/calculate-activity-size.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/calculate-activity-size.ts new file mode 100644 index 0000000..8d2240b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/calculate-activity-size.ts @@ -0,0 +1,47 @@ +import {activityTagName, createActivityElement} from "../internal/create-activity-element"; +import {Activity, Size} from "../models"; + +export function calculateActivitySize(activity: Activity): Promise { + const wrapper = document.createElement('div'); + const dummyActivityElement = createActivityElement(activity, true); + wrapper.style.position = 'absolute'; + wrapper.appendChild(dummyActivityElement); + + // Append the temporary element to the DOM. + const bodyElement = document.getElementsByTagName('body')[0]; + bodyElement.append(wrapper); + + // Wait for the activity element to be completely rendered. + // When using custom elements, they are rendered after they are mounted. Before then, they have a 0 width and height. + return new Promise((resolve, reject) => { + const checkSize = () => { + const activityElement: Element = wrapper.getElementsByTagName(activityTagName)[0]; + + if(activityElement == null) { + reject('Activity element not found.'); + return; + } + + const activityElementRect = activityElement.getBoundingClientRect(); + + // If the custom element has no width or height yet, it means it has not yet rendered. + if (activityElementRect.width == 0 || activityElementRect.height == 0) { + // Request an animation frame and call ourselves back immediately after. + window.requestAnimationFrame(checkSize); + } else { + const rect = wrapper.getElementsByClassName("elsa-activity")[0].getBoundingClientRect(); + const width = rect.width; + const height = rect.height; + + // Remove the temporary element (used only to calculate its size). + wrapper.remove(); + + // Update the size of the activity node and resolve the promise. + resolve({width, height}); + } + }; + + // Begin to try to get our element size. + checkSize(); + }); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/center-content.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/center-content.ts new file mode 100644 index 0000000..3fc03d4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/center-content.ts @@ -0,0 +1,10 @@ +import {graphBindings} from "./graph-bindings"; + +export function centerContent(graphId: string) { + const {graph} = graphBindings[graphId]; + + graph.centerContent({ + padding: 20, + useCellGeometry: true + }); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/create-graph.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/create-graph.ts new file mode 100644 index 0000000..7b491b9 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/create-graph.ts @@ -0,0 +1,392 @@ +import {Graph, Shape, Node, Edge} from '@antv/x6'; +import {Selection} from "@antv/x6-plugin-selection"; +import {Snapline} from "@antv/x6-plugin-snapline"; +import {Transform} from "@antv/x6-plugin-transform"; +import {Keyboard} from "@antv/x6-plugin-keyboard"; +import {Clipboard} from '@antv/x6-plugin-clipboard'; +import {History} from '@antv/x6-plugin-history'; +import {DotNetComponentRef, graphBindings} from "./graph-bindings"; +import {DotNetFlowchartDesigner} from "./dotnet-flowchart-designer"; +import {Activity} from "../models"; + +export async function createGraph(containerId: string, componentRef: DotNetComponentRef, readOnly: boolean, settings?: any): Promise { + const containerElement = document.getElementById(containerId); + const interop = new DotNetFlowchartDesigner(componentRef); + let lastSelectedNode: Node.Properties = null; + + const graph = new Graph({ + container: containerElement, + autoResize: true, + grid: { + type: settings?.grid?.type || 'dot', + visible: settings?.grid?.visible || true, + size: settings?.grid?.size || 10, + args: settings?.grid?.args || { + color: '#334154', + thickness: 1, + } + }, + magnetThreshold: settings?.magnetThreshold || 0, + panning: settings?.panning || { + enabled: true, + }, + mousewheel: settings?.mousewheel || { + enabled: true, + factor: 1.05, + minScale: 0.4, + maxScale: 3, + }, + interacting: { + nodeMovable: () => !readOnly, + arrowheadMovable: () => !readOnly, + edgeMovable: () => !readOnly, + vertexMovable: () => !readOnly, + vertexAddable: () => !readOnly, + vertexDeletable: () => !readOnly, + edgeLabelMovable: () => !readOnly, + magnetConnectable: () => !readOnly, + toolsAddable: () => !readOnly, + useEdgeTools: () => !readOnly, + }, + connecting: { + router: 'manhattan', + connector: { + name: 'rounded', + args: { + radius: 8, + }, + }, + anchor: 'center', + connectionPoint: 'anchor', + allowBlank: false, + snap: { + radius: 20, + anchor: "bbox" + }, + createEdge() { + return graph.createEdge({ + shape: 'elsa-edge', + attrs: { + line: { + strokeDasharray: '5 5', + }, + }, + zIndex: -1, + }) + }, + validateConnection({sourceMagnet, targetMagnet}) { + if (!sourceMagnet || sourceMagnet.getAttribute('port-group') === 'in') { + return false + } + + if (!targetMagnet || targetMagnet.getAttribute('port-group') !== 'in') { + return false + } + + return true + }, + }, + highlighting: { + magnetAdsorbed: { + name: 'stroke', + args: { + attrs: { + fill: '#fff', + stroke: '#31d0c6', + strokeWidth: 4, + }, + }, + }, + embedding: { + name: 'stroke', + args: { + padding: -1, + attrs: { + stroke: '#73d13d', + }, + }, + }, + } + }); + + graph.use( + new History({ + enabled: true, + beforeAddCommand: (e: string, args: any) => { + if (args.key == 'tools') + return false; + + const supportedEvents = ['cell:added', 'cell:removed', 'cell:change:*']; + return supportedEvents.indexOf(e) >= 0; + }, + }), + ) + + graph.use(new Snapline({ + enabled: true, + className: 'elsa-snapline', + })); + + graph.use( + new Selection({ + enabled: true, + multiple: !readOnly, + modifiers: ['ctrl', 'shift'], + rubberEdge: false, + rubberNode: true, + rubberband: true, + movable: !readOnly, + showNodeSelectionBox: true, + className: 'elsa-selection' + }), + ); + + if (!readOnly) { + graph.use( + new Keyboard({ + enabled: true + }) + ); + + graph.use( + new Clipboard({ + enabled: true, + }), + ) + + graph.use( + new Transform({ + resizing: { + enabled: true, + + } + }) + ); + + // Copy the cells in the graph to the internal clipboard with Ctrl+C. + graph.bindKey(['ctrl+c', 'meta+c'], () => { + const cells = graph.getSelectedCells() + if (cells.length) { + graph.copy(cells) + } + + return false; + }); + + graph.bindKey(['meta+x', 'ctrl+x'], () => { + const cells = graph.getSelectedCells() + if (cells.length) { + graph.cut(cells) + } + + return false; + }); + + // Paste + graph.bindKey(['ctrl+v', 'meta+v'], () => { + if (!graph.isClipboardEmpty()) { + const cells = graph.getCellsInClipboard(); + + if (cells.length == 0) + return; + + const activityCells = cells.filter(x => x.shape == 'elsa-activity'); + const edgeCells: Edge[] = cells.filter(x => x.shape == 'elsa-edge'); + + interop.raisePasteCellsRequested(activityCells, edgeCells); + } + + return false; + }); + + // Undo + graph.bindKey(['meta+z', 'ctrl+z'], () => { + if (graph.canUndo()) { + graph.undo() + } + return false + }); + + // Redo + graph.bindKey(['meta+y', 'ctrl+y'], () => { + if (graph.canRedo()) { + graph.redo() + } + return false + }); + + // Delete + graph.bindKey('del', () => { + const cells = graph.getSelectedCells() + if (cells.length) { + graph.removeCells(cells) + } + + return false; + }); + } + + // Select all + graph.bindKey(['meta+a', 'ctrl+a'], () => { + const nodes = graph.getNodes() + if (nodes) { + graph.select(nodes) + } + + return false; + }); + + // zoom + graph.bindKey(['ctrl+1', 'meta+1'], () => { + const zoom = graph.zoom() + if (zoom < 1.5) { + graph.zoom(0.1) + } + return false; + }); + + graph.bindKey(['ctrl+2', 'meta+2'], () => { + const zoom = graph.zoom() + if (zoom > 0.5) { + graph.zoom(-0.1) + } + return false; + }); + + graph.on('blank:click', async () => { + if (!!lastSelectedNode) { + lastSelectedNode.setProp('selected-port', null); + } + await interop.raiseCanvasSelected(); + return false; + }); + + // Move the clicked node to the front. This helps when the user clicks on a node that is behind another node. + graph.on('node:mousedown', ({node}) => { + node.toFront(); + return false; + }); + + // Change the edge's color and style when it is connected to a magnet. + graph.on('edge:connected', ({edge}) => { + edge.attr({ + line: { + strokeDasharray: '', + }, + }); + return false; + }); + + graph.on("edge:mouseenter", ({cell}) => { + cell.addTools([ + {name: "vertices"}, + { + name: "button-remove", + args: {distance: 20}, + }, + ]); + return false; + }); + + graph.on("edge:mouseleave", ({cell}) => { + if (cell.hasTool("button-remove")) { + cell.removeTool("button-remove"); + } + return false; + }); + + graph.on('node:click', async args => { + const {e, node} = args; + const activity: Activity = node.data; + const activityId = activity.id; + const activityElementId = `activity-${activityId}`; + const activityElement = document.getElementById(activityElementId); + const menuButtonElement = activityElement.querySelector('.mud-button-root'); + const embeddedPortElements = activityElement.querySelectorAll('.embedded-port'); + const mousePosition = graph.clientToLocal(e.clientX, e.clientY); + + // Check if the menu button was clicked. + const menuButtonElementRect = menuButtonElement.getBoundingClientRect(); + const menuButtonElementBBox = graph.pageToLocal(menuButtonElementRect); + + if (menuButtonElementBBox.containsPoint(mousePosition)) { + await interop.raiseActivityMenuButtonClicked(activity); + return; + } + + // Check which of the embedded ports intersect with the selected node. + for (let i = 0; i < embeddedPortElements.length; i++) { + const embeddedPortElement = embeddedPortElements[i]; + const embeddedPortElementRect = embeddedPortElement.getBoundingClientRect(); + const embeddedPortElementBBox = graph.pageToLocal(embeddedPortElementRect); + + if (!embeddedPortElementBBox.containsPoint(mousePosition)) + continue; + + // Mark the node as unselected. + if (graph.isSelected(node)) { + graph.unselect(node); + } + + const embeddedPortName = embeddedPortElement.getAttribute('data-port-name'); + node.setProp('selected-port', embeddedPortName); + lastSelectedNode = node; + + await interop.raiseActivityEmbeddedPortSelected(activity, embeddedPortName); + return; + } + + if (!graph.isSelected(node)) { + graph.select(node); + } + + node.setProp('selected-port', null); + }); + + graph.on('node:dblclick', async args => { + const {node} = args; + const activity: Activity = node.data; + await interop.raiseActivityDoubleClick(activity); + }); + + graph.on('node:selected', async args => { + const {node} = args; + const activity: Activity = node.data; + await interop.raiseActivitySelected(activity); + }); + + const onGraphUpdated = async (e: any) => { + await interop.raiseGraphUpdated(); + return false; + }; + + const onNodeRemoved = async (e: any) => { + await onGraphUpdated(e); + return false; + }; + + const onNodeAdded = async (e: any) => { + await onGraphUpdated(e); + return false; + }; + + graph.on('node:moved', onGraphUpdated); + graph.on('node:added', onNodeAdded); + graph.on('node:removed', onNodeRemoved); + graph.on('node:change:size', onGraphUpdated); + graph.on('edge:removed', onGraphUpdated); + graph.on('edge:connected', onGraphUpdated); + graph.on('edge:vertexs:added', onGraphUpdated); + graph.on('edge:vertexs:removed', onGraphUpdated); + + // Register the graph. + const graphId = containerId; + + graphBindings[graphId] = { + graphId: graphId, + graph: graph, + interop: interop + }; + + return graphId; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/dispose-graph.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/dispose-graph.ts new file mode 100644 index 0000000..64454f5 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/dispose-graph.ts @@ -0,0 +1,5 @@ +import {graphBindings} from "./graph-bindings"; + +export function disposeGraph(graphId) { + delete graphBindings[graphId]; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/dotnet-flowchart-designer.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/dotnet-flowchart-designer.ts new file mode 100644 index 0000000..fd4f3d9 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/dotnet-flowchart-designer.ts @@ -0,0 +1,56 @@ +import {DotNetComponentRef} from "./graph-bindings"; +import {Activity} from "../models"; + +export class DotNetFlowchartDesigner { + constructor(private componentRef: DotNetComponentRef) { + } + + /// + /// Raises the event. + /// + async raiseActivitySelected(activity: Activity): Promise { + await this.componentRef.invokeMethodAsync('HandleActivitySelected', activity); + } + + /// + /// Raises the event. + /// + async raiseActivityMenuButtonClicked(activity: Activity): Promise { + await this.componentRef.invokeMethodAsync('HandleActivityMenuButtonClicked', activity); + } + + /// + /// Raises the event. + /// + async raiseActivityEmbeddedPortSelected(activity: Activity, portName: string): Promise { + await this.componentRef.invokeMethodAsync('HandleActivityEmbeddedPortSelected', activity, portName); + } + + /// + /// Raises the event. + /// + async raiseActivityDoubleClick(activity: Activity): Promise { + await this.componentRef.invokeMethodAsync('HandleActivityDoubleClick', activity); + } + + /// + /// Raises the event. + /// + async raiseCanvasSelected(): Promise { + await this.componentRef.invokeMethodAsync('HandleCanvasSelected'); + } + + /// + /// Raises the event. + /// + async raiseGraphUpdated(): Promise { + await this.componentRef.invokeMethodAsync('HandleGraphUpdated'); + } + + /// + /// Raises the event. + /// + async raisePasteCellsRequested(activityCells: any[], edgeCells: any[]): Promise { + await this.componentRef.invokeMethodAsync('HandlePasteCellsRequested', activityCells, edgeCells); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/graph-bindings.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/graph-bindings.ts new file mode 100644 index 0000000..d6e652a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/graph-bindings.ts @@ -0,0 +1,18 @@ +import {Graph} from '@antv/x6'; +import {DotNetFlowchartDesigner} from "./dotnet-flowchart-designer"; + +// This is a global dictionary that is used to store graph instances. +export const graphBindings: { [key: string]: GraphBinding } = {}; + +// A dotnet component reference. +export interface DotNetComponentRef { + invokeMethodAsync(methodName: string, ...args: any[]): Promise; + dispose(): void; +} + +export interface GraphBinding { + graphId: string; + graph: Graph; + interop: DotNetFlowchartDesigner; +} + diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/index.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/index.ts new file mode 100644 index 0000000..6fc1487 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/index.ts @@ -0,0 +1,19 @@ +export * from './add-activity-node'; +export * from './calculate-activity-size'; +export * from './center-content'; +export * from './create-graph'; +export * from './dispose-graph'; +export * from './graph-bindings'; +export * from './load-graph'; +export * from './paste-cells'; +export * from './read-graph'; +export * from './raise-activity-selected'; +export * from './raise-activity-embedded-port-selected'; +export * from './select-activity'; +export * from './set-grid-color'; +export * from './update-activity'; +export * from './update-activity-size'; +export * from './update-activity-stats'; +export * from './zoom-to-fit'; +export * from './auto-layout'; +export {DotNetFlowchartDesigner} from "./dotnet-flowchart-designer"; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/load-graph.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/load-graph.ts new file mode 100644 index 0000000..adc2934 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/load-graph.ts @@ -0,0 +1,27 @@ +import {Graph, Model} from '@antv/x6'; +import {graphBindings} from "./graph-bindings"; + +export function loadGraph(graphId: string, data: string | Model.FromJSONData) { + const {graph} = graphBindings[graphId]; + const model = typeof data === 'string' ? JSON.parse(data) : data; + graph.fromJSON(model); + + waitUntilCanvasHasNonZeroHeight(graph).then(() => graph.centerContent({padding: 20})); +} + +function waitUntilCanvasHasNonZeroHeight(graph: Graph): Promise { + const container = graph.container; + + return new Promise((resolve, reject) => { + const checkSize = () => { + const clientRect = container.getBoundingClientRect(); + + if (clientRect.height == 0) + window.requestAnimationFrame(checkSize); + else + resolve(); + }; + + checkSize(); + }); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/paste-cells.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/paste-cells.ts new file mode 100644 index 0000000..d382278 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/paste-cells.ts @@ -0,0 +1,21 @@ +import {Cell, Node, Edge} from "@antv/x6"; +import {graphBindings} from "./graph-bindings"; + +export async function pasteCells(graphId: string, nodeProps: Node.Properties[], edgeProps: Edge.Properties[]) { + // Get graph reference. + const {graph} = graphBindings[graphId]; + + // Create nodes and edges from node props and edge props. + const nodes = nodeProps.map(x => graph.createNode(x)); + const edges = edgeProps.map(x => graph.createEdge(x)); + + // Add the nodes and edges to the graph. + graph.addCell(nodes); + graph.addCell(edges); + + // Wait for the new cells to be rendered. + requestAnimationFrame(() => { + graph.cleanSelection(); + graph.select([...nodes, ...edges]); + }); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/raise-activity-embedded-port-selected.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/raise-activity-embedded-port-selected.ts new file mode 100644 index 0000000..f65302f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/raise-activity-embedded-port-selected.ts @@ -0,0 +1,21 @@ +import {Activity} from "../models"; +import {graphBindings} from "./graph-bindings"; + +export async function raiseActivityEmbeddedPortSelected(elementId: string, activityModel: Activity | string, portName: string) { + // Get wrapper element. + const wrapper = document.getElementById(elementId); + + // Get container element. + const container = wrapper.closest('.graph-container'); + + // Get graph ID. + const graphId = container.id; + + // Get graph reference. + const {interop} = graphBindings[graphId]; + + // Parse activity model. + const activity = typeof activityModel === 'string' ? JSON.parse(activityModel) : activityModel; + + await interop.raiseActivityEmbeddedPortSelected(activity, portName); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/raise-activity-selected.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/raise-activity-selected.ts new file mode 100644 index 0000000..cbd6e28 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/raise-activity-selected.ts @@ -0,0 +1,21 @@ +import {Activity} from "../models"; +import {graphBindings} from "./graph-bindings"; + +export async function raiseActivitySelected(elementId: string, activityModel: Activity | string) { + // Get wrapper element. + const wrapper = document.getElementById(elementId); + + // Get container element. + const container = wrapper.closest('.graph-container'); + + // Get graph ID. + const graphId = container.id; + + // Get graph reference. + const {interop} = graphBindings[graphId]; + + // Parse activity model. + const activity = typeof activityModel === 'string' ? JSON.parse(activityModel) : activityModel; + + await interop.raiseActivitySelected(activity); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/read-graph.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/read-graph.ts new file mode 100644 index 0000000..e8bc211 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/read-graph.ts @@ -0,0 +1,28 @@ +import {Cell, Edge} from '@antv/x6'; +import {graphBindings} from "./graph-bindings"; + +export function readGraph(graphId: string): { + cells: Cell.Properties[]; +} { + const {graph} = graphBindings[graphId]; + const model = graph.toJSON(); + + // Filter out edges that don't have both a star and end node. + model.cells = model.cells.filter((cell: Cell.Properties) => { + + if(cell.shape == 'elsa-activity') + return true; + + if(cell.shape == 'elsa-edge') + { + const edge = cell as any; + + if(!!edge.source?.cell && !!edge.target?.cell) + return true; + } + + return false; + }); + + return model; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/select-activity.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/select-activity.ts new file mode 100644 index 0000000..b889932 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/select-activity.ts @@ -0,0 +1,34 @@ +import {graphBindings} from "./graph-bindings"; + +export async function selectActivity(elementId: string, activityId: string) { + // Get wrapper element. + const wrapper = document.getElementById(elementId); + + if (wrapper == null) { + console.warn(`Could not find wrapper element with ID ${elementId}`); + return; + } + + // Get container element. + const container = wrapper.closest('.graph-container'); + + // Get graph ID. + const graphId = container.id; + + // Get graph reference. + const {graph} = graphBindings[graphId]; + + // Get activity node. + const node = graph.getNodes().find(x => x.id == activityId); + + if (node == null) { + console.warn(`Could not find node with ID ${activityId} in graph ${graphId}`); + return; + } + + // Select the node. + graph.select(node); + + // Center the selected node. + graph.centerCell(node); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/set-grid-color.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/set-grid-color.ts new file mode 100644 index 0000000..e8a8313 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/set-grid-color.ts @@ -0,0 +1,6 @@ +import {graphBindings} from "./graph-bindings"; + +export function setGridColor(graphId: string, color: string) { + const {graph} = graphBindings[graphId]; + graph.grid.update({color: color}); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity-size.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity-size.ts new file mode 100644 index 0000000..c49c5ce --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity-size.ts @@ -0,0 +1,49 @@ +import {calculateActivitySize} from "./calculate-activity-size"; +import {Activity, Size} from "../models"; +import {graphBindings} from "./graph-bindings"; + +export async function updateActivitySize(elementId: string, activityModel: Activity | string, size?: Size) { + // Get wrapper element. + const wrapper = document.getElementById(elementId); + + if (wrapper == null) { + console.warn(`Could not find wrapper element with ID ${elementId}`); + return; + } + + // Get container element. + const container = wrapper.closest('.graph-container'); + + // Get graph ID. + const graphId = container.id; + + // Get graph reference. + const {graph} = graphBindings[graphId]; + + // Parse activity model. + const activity = typeof activityModel === 'string' ? JSON.parse(activityModel) : activityModel; + + // Calculate the size of the activity. + const rect = await calculateActivitySize(activity); + let width = rect.width; + let height = rect.height; + + // Get the node from the graph and update its size. + const activityId = activity.id; + const node = graph.getNodes().find(x => x.id == activityId); + + if (node == null) { + console.warn(`Could not find node with ID ${activityId} in graph ${graphId}`); + return; + } + + if (!!size) { + if (size.width > width) + width = size.width; + + if (size.height > height) + height = size.height; + } + + node.size(width, height); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity-stats.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity-stats.ts new file mode 100644 index 0000000..6f1caf2 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity-stats.ts @@ -0,0 +1,31 @@ +import {ActivityStats} from "../models"; +import {graphBindings} from "./graph-bindings"; + +export async function updateActivityStats(elementId: string, activityId: string, activityStats: ActivityStats) { + // Get wrapper element. + const wrapper = document.getElementById(elementId); + + if (wrapper == null) { + console.warn(`Could not find wrapper element with ID ${elementId}`); + return; + } + + // Get container element. + const container = wrapper.closest('.graph-container'); + + // Get graph ID. + const graphId = container.id; + + // Get graph reference. + const {graph} = graphBindings[graphId]; + + // Get the node from the graph and update its size. + const node = graph.getNodes().find(x => x.id == activityId); + + if (node == null) { + console.warn(`Could not find node with ID ${activityId} in graph ${graphId}`); + return; + } + + node.setProp('activityStats', activityStats); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity.ts new file mode 100644 index 0000000..8afcc20 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/update-activity.ts @@ -0,0 +1,41 @@ +import {Node} from "@antv/x6"; +import {Activity} from "../models"; +import {graphBindings} from "./graph-bindings"; +import {Ports} from "../models/x6"; + +export async function updateActivity(graphId: string, activity: Activity, ports?: Ports) { + // Get graph reference. + const {graph, interop} = graphBindings[graphId]; + + // Get the node from the graph. + const activityId = activity.id; + let node = graph.getNodes().find(x => x.id == activityId); + + // Update the node data. + if (!!node) { + + // Update the node's data with the activity. + node.setData(activity, {overwrite: true}); + + // Update ports. + if (!!ports) { + updatePorts(node, ports); + } + + // Publish changed event. + await interop.raiseGraphUpdated(); + } +} + +const updatePorts = (node: Node, ports: Ports) => { + const desiredPorts = ports.items; + const actualPorts = node.ports.items; + const addedPorts = desiredPorts.filter(x => !actualPorts.some(y => y.id == x.id)); + const removedPorts = actualPorts.filter(x => !desiredPorts.some(y => y.id == x.id)); + + if (addedPorts.length > 0) + node.addPorts(addedPorts); + + if (removedPorts.length > 0) + node.removePorts(removedPorts); +}; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/zoom-to-fit.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/zoom-to-fit.ts new file mode 100644 index 0000000..d0be583 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/zoom-to-fit.ts @@ -0,0 +1,10 @@ +import {graphBindings} from "./graph-bindings"; + +export function zoomToFit(graphId: string) { + const {graph} = graphBindings[graphId]; + graph.zoomToFit({ + padding: 20, + minScale: 0.5, + maxScale: 3 + }); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/internal/create-activity-element.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/internal/create-activity-element.ts new file mode 100644 index 0000000..0563e5b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/internal/create-activity-element.ts @@ -0,0 +1,24 @@ +import {Activity, ActivityStats} from "../models"; + +export const activityTagName = "elsa-activity-wrapper"; + +export function createActivityElement(activity: Activity, detached?: boolean, selectedPort?: string, stats?: ActivityStats): HTMLElement { + const activityElement = document.createElement(activityTagName) as any; + const activityId = activity.id; + const elementId = `activity-${activityId}`; + + if(!detached) { + activityElement.id = elementId; + activityElement.setAttribute("element-id", elementId); + } + + if(!!selectedPort) + activityElement.setAttribute("selected-port-name", selectedPort); + + activityElement.stats = stats; + //activityElement.activity = activity; // activity can be too deeply nested when dealing with workflow definition activities, exceeding the max depth of 32 with JSInterop. + activityElement.setAttribute("activity-json", JSON.stringify(activity)); + activityElement.setAttribute("activity-id", activityId); + + return activityElement; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/internal/init.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/internal/init.ts new file mode 100644 index 0000000..7478216 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/internal/init.ts @@ -0,0 +1,80 @@ +import {Graph, Shape} from '@antv/x6'; +import {createActivityElement} from "./create-activity-element"; +import {Activity} from "../models"; + +export function initialize() { + + Shape.HTML.register({ + shape: "elsa-activity", + effect: ["data", "activityStats"], + html(cell) { + const activity: Activity = cell.getData(); + const selectedPort = cell.prop('selected-port'); + const activityStats = cell.prop('activityStats'); + return createActivityElement(activity, false, selectedPort, activityStats); + }, + ports: { + groups: { + in: { + position: "left", + attrs: { + circle: { + r: 5, + magnet: true, + stroke: "#0ea5e9", + strokeWidth: 2, + fill: "#fff", + }, + text: { + fontSize: 12, + fill: "#888", + }, + }, + label: { + position: { + name: "outside", + }, + }, + }, + out: { + position: "right", + attrs: { + circle: { + r: 5, + magnet: true, + stroke: "#fff", + strokeWidth: 2, + fill: "#0ea5e9", + }, + text: { + fontSize: 12, + fill: "#888", + }, + }, + label: { + position: { + name: "outside", + }, + }, + }, + }, + } + }); + + Graph.registerEdge( + 'elsa-edge', + { + inherit: 'edge', + attrs: { + line: { + stroke: '#C2C8D5', + strokeWidth: 1, + targetMarker: 'classic', + size: 6, + }, + }, + }, + true, + ); + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/activity-stats.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/activity-stats.ts new file mode 100644 index 0000000..3b521af --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/activity-stats.ts @@ -0,0 +1,6 @@ +export interface ActivityStats { + started: number; + completed: number; + uncompleted: number; + blocked: boolean; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/activity.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/activity.ts new file mode 100644 index 0000000..41f6e1e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/activity.ts @@ -0,0 +1,14 @@ +import {ActivityDesignerMetadata, ActivityDisplayTextMetadata} from "./metadata"; + +export interface Activity { + id: string; + type: string; + version: number; + metadata: any | ActivityDisplayTextMetadata | ActivityDesignerMetadata; + canStartWorkflow?: boolean; + runAsynchronously?: boolean; + customProperties?: any; + + [name: string]: any; +} + diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/connection.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/connection.ts new file mode 100644 index 0000000..686b10c --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/connection.ts @@ -0,0 +1,6 @@ +export interface Connection { + source: string; + target: string; + sourcePort: string; + targetPort: string; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/container.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/container.ts new file mode 100644 index 0000000..7f1a4f9 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/container.ts @@ -0,0 +1,5 @@ +import {Activity} from "./activity"; + +export interface Container extends Activity { + activities: Array; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/index.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/index.ts new file mode 100644 index 0000000..471c2e3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/index.ts @@ -0,0 +1,6 @@ +export * from './activity'; +export * from './activity-stats'; +export * from './connection'; +export * from './container'; +export * from "./metadata"; +export * from './size'; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/metadata.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/metadata.ts new file mode 100644 index 0000000..4ab4354 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/metadata.ts @@ -0,0 +1,12 @@ +export interface ActivityDisplayTextMetadata { + displayText?: string; +} + +export interface ActivityDesignerMetadata { + designer: { + position: { + x: number; + y: number; + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/size.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/size.ts new file mode 100644 index 0000000..a535bd4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/size.ts @@ -0,0 +1,4 @@ +export interface Size { + width: number; + height: number; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/x6.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/x6.ts new file mode 100644 index 0000000..f5a528a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/models/x6.ts @@ -0,0 +1,17 @@ +export interface Port { + id: string; + group?: string; +} + +export interface Ports +{ + items: Port[]; +} + +export interface Node +{ + id: string; + ports: Ports; + addPorts(ports: Port[]): void + removePorts(ports: Port[]): void +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/tsconfig.json b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/tsconfig.json new file mode 100644 index 0000000..5b77e76 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "outDir": "../wwwroot", + "sourceMap": true, + "noImplicitAny": false, + "module": "ES2022", + "target": "ES2022", + "jsx": "react", + "allowJs": true, + "moduleResolution": "node" + }, + "include": [ + "./src/**/*" + ] +} diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/webpack.config.js b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/webpack.config.js new file mode 100644 index 0000000..568603d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/webpack.config.js @@ -0,0 +1,53 @@ +const path = require('path'); +const CopyPlugin = require('copy-webpack-plugin'); + +module.exports = { + entry: { + designer: './src/designer.ts' + }, + output: { + filename: '[name].entry.js', + path: path.resolve(__dirname, '..', 'wwwroot'), + library: { + type: "module", + }, + module: true, // Enable outputting ES6 modules. + environment: { + module: true, // The environment supports ES6 modules. + }, + }, + experiments: { + outputModule: true, // This enables the experimental support for outputting ES6 modules + }, + devtool: 'source-map', + mode: 'development', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + { + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }, + { + test: /\.(eot|woff(2)?|ttf|otf|svg)$/i, + type: 'asset' + }, + ] + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + plugins: [ + new CopyPlugin({ + patterns: [ + {from: 'css/designer.v1.css', to: './'}, + {from: 'css/designer.v2.css', to: './'}, + {from: 'css/designer.v2.css', to: './designer.css'}, // Default + ], + }), + ] +}; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/ActivityWrapperBase.cs b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/ActivityWrapperBase.cs new file mode 100644 index 0000000..554d94b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/ActivityWrapperBase.cs @@ -0,0 +1,102 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Components; +using Elsa.Studio.Workflows.Designer.Interop; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Designer.Components.ActivityWrappers; + +/// +/// A wrapper for an activity component. +/// +public abstract class ActivityWrapperBase : StudioComponentBase +{ + /// + /// Gets or sets the element ID. + /// + [Parameter] public string? ElementId { get; set; } + + /// + /// Gets or sets the activity ID. + /// + [Parameter] public string ActivityId { get; set; } = null!; + + /// + /// Gets or sets the activity. + /// + [Parameter] public JsonObject Activity { get; set; } = null!; + + /// + /// Until the max depth of JSInterop is configurable to exceed 32, we need to pass the activity JSON as a string. + /// + [Parameter] public string ActivityJson { get; set; } = null!; + + /// + /// Gets or sets the selected port name. + /// + [Parameter] public string? SelectedPortName { get; set; } + + /// + /// Gets or sets the activity stats. + /// + [Parameter] public ActivityStats? Stats { get; set; } + + [Inject] protected DesignerJsInterop DesignerInterop { get; set; } = null!; + [Inject] protected IActivityRegistry ActivityRegistry { get; set; } = null!; + [Inject] protected IActivityDisplaySettingsRegistry ActivityDisplaySettingsRegistry { get; set; } = null!; + [Inject] protected IActivityPortService ActivityPortService { get; set; } = null!; + [Inject] protected IServiceProvider ServiceProvider { get; set; } = null!; + + protected bool CanStartWorkflow => Activity.GetCanStartWorkflow() == true; + protected string Label { get; private set; } = null!; + protected string TypeName { get; private set; } = null!; + protected string Description { get; private set; } = null!; + protected bool ShowDescription { get; private set; } + protected string Color { get; private set; } = null!; + protected string? Icon { get; private set; } + protected ActivityDescriptor? ActivityDescriptor { get; private set; } + protected ICollection Ports { get; private set; } = new List(); + + /// + protected override async Task OnParametersSetAsync() + { + if (!string.IsNullOrWhiteSpace(ActivityJson)) + Activity = JsonSerializer.Deserialize(ActivityJson, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })!; + + await ActivityRegistry.EnsureLoadedAsync(); + + var activity = Activity; + var activityDisplayText = activity.GetDisplayText()?.Trim(); + var activityDescription = activity.GetDescription()?.Trim(); + var activityType = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var descriptor = ActivityRegistry.Find(activityType, activityVersion); + var displaySettings = ActivityDisplaySettingsRegistry.GetSettings(activityType); + + Label = !string.IsNullOrEmpty(activityDisplayText) ? activityDisplayText : descriptor?.DisplayName ?? descriptor?.Name ?? "Unknown Activity"; + TypeName = descriptor?.DisplayName ?? "Unknown Activity"; + Description = !string.IsNullOrEmpty(activityDescription) ? activityDescription : descriptor?.Description ?? string.Empty; + ShowDescription = activity.GetShowDescription() == true; + Color = displaySettings.Color; + Icon = displaySettings.Icon; + ActivityDescriptor = descriptor!; + Ports = descriptor != null ? ActivityPortService.GetPorts(new PortProviderContext(descriptor, activity)).ToList() : []; + + await UpdateSizeAsync(); + } + + private async Task UpdateSizeAsync() + { + if (!string.IsNullOrEmpty(ElementId)) + { + var size = Activity.GetDesignerMetadata().Size; + await DesignerInterop.UpdateActivitySizeAsync(ElementId, Activity, size); + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/EmbeddedActivityWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/EmbeddedActivityWrapper.razor.cs new file mode 100644 index 0000000..c9ecf2a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/EmbeddedActivityWrapper.razor.cs @@ -0,0 +1,52 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Components; +using Elsa.Studio.Workflows.Designer.Interop; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Designer.Components.ActivityWrappers; + +public abstract class EmbeddedActivityWrapperBase : StudioComponentBase +{ + [Parameter] public string? ElementId { get; set; } + [Parameter] public string ActivityId { get; set; } = null!; + [Parameter] public JsonObject Activity { get; set; } = null!; + [Parameter] public bool IsSelected { get; set; } + + [Inject] DesignerJsInterop DesignerInterop { get; set; } = null!; + [Inject] IActivityRegistry ActivityRegistry { get; set; } = null!; + [Inject] IActivityDisplaySettingsRegistry ActivityDisplaySettingsRegistry { get; set; } = null!; + [Inject] IServiceProvider ServiceProvider { get; set; } = null!; + + protected bool CanStartWorkflow => Activity.GetCanStartWorkflow() == true; + protected string Label { get; private set; } = null!; + protected string Description { get; private set; } = null!; + protected bool ShowDescription { get; private set; } + protected string Color { get; private set; } = null!; + protected string? Icon { get; private set; } + protected ActivityDescriptor ActivityDescriptor { get; private set; } = null!; + + /// + protected override async Task OnInitializedAsync() + { + await ActivityRegistry.EnsureLoadedAsync(); + + var activity = Activity; + var activityType = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var descriptor = (ActivityRegistry.Find(activityType, activityVersion) ?? ActivityRegistry.Find("Elsa.UnknownActivity"))!; + var activityDisplayText = activity.GetDisplayText()?.Trim() ?? activity.GetName() ?? descriptor.DisplayName ?? descriptor.Name; + var activityDescription = activity.GetDescription()?.Trim(); + var displaySettings = ActivityDisplaySettingsRegistry.GetSettings(activityType); + + Label = activityDisplayText; + Description = !string.IsNullOrEmpty(activityDescription) ? activityDescription : descriptor.Description ?? string.Empty; + ShowDescription = activity.GetShowDescription() == true; + Color = displaySettings.Color; + Icon = displaySettings.Icon; + ActivityDescriptor = descriptor; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/ActivityWrapper.razor b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/ActivityWrapper.razor new file mode 100644 index 0000000..a9558f0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/ActivityWrapper.razor @@ -0,0 +1,70 @@ +@using System.Text.Json +@using System.Text.Json.Nodes +@using Elsa.Api.Client.Resources.ActivityDescriptors.Enums +@using Elsa.Api.Client.Extensions +@using Elsa.Studio.Workflows.Domain.Contexts +@inherits ActivityWrapperBase +@inject ILocalizer Localizer +@{ + const string white = "#ffffff"; + var colorStyle = CanStartWorkflow ? $"color: {white};" : ""; + var metadata = Stats?.Metadata; + var hasRetryAttempts = metadata != null && metadata.TryGetValue("HasRetryAttempts", out var hasRetryAttemptsValue) && hasRetryAttemptsValue is JsonElement { ValueKind: JsonValueKind.True }; + var color = Stats == null ? MudBlazor.Color.Transparent : Stats.Faulted ? MudBlazor.Color.Error : Stats.Blocked ? MudBlazor.Color.Warning : Stats.Uncompleted > Stats.Completed ? MudBlazor.Color.Info : Stats.Completed > 0 ? MudBlazor.Color.Success : MudBlazor.Color.Default; + var content = Stats == null ? null : Stats.Faulted || Stats.Blocked ? Stats.Started.ToString() : Stats.Completed.ToString(); + var icon = Stats == null ? null : content == null ? Stats.Blocked ? Icons.Material.Outlined.HourglassTop : Stats.Uncompleted > 0 ? Icons.Material.Outlined.PlayArrow : null : null; + var showBadge = Stats != null; + var cssClass = hasRetryAttempts ? "elsa-activity-wrapper-badge has-retries" : "elsa-activity-wrapper-badge"; + + + + + @if (Icon != null) + { + + } + + @Localizer[Label] + @{ + var visiblePorts = Ports.Where(x => x is { Type: PortType.Embedded, IsBrowsable: true }).ToList(); + } + @if (visiblePorts.Any()) + { + + @foreach (var port in visiblePorts) + { + var portName = port.Name; + var providerContext = new PortProviderContext(ActivityDescriptor, Activity); + var portProvider = ActivityPortService.GetProvider(providerContext); + var childActivity = portProvider.ResolvePort(portName, new(ActivityDescriptor, Activity)); + + @if (childActivity != null) + { + +
+ +
+
+ } + else + { + + @port.DisplayName + + } + } +
+ } + + @if (!string.IsNullOrWhiteSpace(Description) && ShowDescription) + { + @Description + } +
+
+
+
+} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/ActivityWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/ActivityWrapper.razor.cs new file mode 100644 index 0000000..55adfa1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/ActivityWrapper.razor.cs @@ -0,0 +1,19 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.Designer.Interop; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Designer.Components.ActivityWrappers.V1; + +/// +/// A wrapper for an activity component. +/// +public partial class ActivityWrapper : ActivityWrapperBase +{ +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/EmbeddedActivityWrapper.razor b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/EmbeddedActivityWrapper.razor new file mode 100644 index 0000000..0b8e55d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/EmbeddedActivityWrapper.razor @@ -0,0 +1,25 @@ +@inherits EmbeddedActivityWrapperBase +@{ + var colorStyle = IsSelected ? $"color: {Color};" : ""; +} + + + @if (Icon != null) + { + + } + + @Label + + @if (!string.IsNullOrWhiteSpace(Description) && ShowDescription) + { + @Description + } + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/EmbeddedActivityWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/EmbeddedActivityWrapper.razor.cs new file mode 100644 index 0000000..c371bc3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V1/EmbeddedActivityWrapper.razor.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Workflows.Designer.Components.ActivityWrappers.V1; + +public partial class EmbeddedActivityWrapper; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/ActivityWrapper.razor b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/ActivityWrapper.razor new file mode 100644 index 0000000..af6e562 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/ActivityWrapper.razor @@ -0,0 +1,105 @@ +@using System.Text.Json +@using Elsa.Api.Client.Resources.ActivityDescriptors.Enums +@using Elsa.Api.Client.Extensions +@using Elsa.Studio.Workflows.Domain.Contexts +@inherits ActivityWrapperBase +@inject ILocalizer Localizer + +@{ + const string white = "#ffffff"; + const string transparent = "rgba(0,0,0,0)"; + var colorStyle = CanStartWorkflow ? $"color: {white};" : ""; + var backgroundColor = CanStartWorkflow ? Color : white; + var iconBgColor = CanStartWorkflow ? transparent : Color; + var iconColor = white; + var menuIconColor = CanStartWorkflow ? white : "var(--mud-palette-text-primary)"; + var metadata = Stats?.Metadata; + var hasRetryAttempts = metadata != null && metadata.TryGetValue("HasRetryAttempts", out var hasRetryAttemptsValue) && hasRetryAttemptsValue is JsonElement { ValueKind: JsonValueKind.True }; + var color = Stats == null ? MudBlazor.Color.Transparent : Stats.Faulted ? MudBlazor.Color.Error : Stats.Blocked ? MudBlazor.Color.Warning : Stats.Uncompleted > Stats.Completed ? MudBlazor.Color.Info : Stats.Completed > 0 ? MudBlazor.Color.Success : MudBlazor.Color.Default; + var content = Stats == null ? null : Stats.Faulted || Stats.Blocked ? Stats.Started.ToString() : Stats.Completed.ToString(); + var icon = Stats == null ? null : content == null ? Stats.Blocked ? Icons.Material.Outlined.HourglassTop : Stats.Uncompleted > 0 ? Icons.Material.Outlined.PlayArrow : null : null; + var showBadge = Stats != null; + var cssClass = hasRetryAttempts ? "elsa-activity-wrapper-badge has-retries" : "elsa-activity-wrapper-badge"; + var visiblePorts = Ports.Where(x => x is { Type: PortType.Embedded, IsBrowsable: true }).ToList(); + var isTrigger = ActivityDescriptor?.Kind == ActivityKind.Trigger; + var toggleCanStartText = isTrigger ? "Trigger" : "Starting point"; +} + + + + + + + + + @if (Icon != null) + { +
+ +
+ } + + +
+ @Localizer[Label] + @Localizer[TypeName] +
+ + +
+ + + + + + + + + + +
+
+ + @if (visiblePorts.Any() && ActivityDescriptor != null) + { +
+ @foreach (var port in visiblePorts) + { + var portName = port.Name; + var providerContext = new PortProviderContext(ActivityDescriptor, Activity); + var portProvider = ActivityPortService.GetProvider(providerContext); + var childActivity = portProvider.ResolvePort(portName, new(ActivityDescriptor, Activity)); + + @if (childActivity != null) + { + +
+ +
+
+ } + else + { + + @port.DisplayName + + } + } +
+ } + + @if (!string.IsNullOrWhiteSpace(Description) && ShowDescription) + { +
+ @Description +
+ } +
+
+
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/ActivityWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/ActivityWrapper.razor.cs new file mode 100644 index 0000000..d041f90 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/ActivityWrapper.razor.cs @@ -0,0 +1,6 @@ +namespace Elsa.Studio.Workflows.Designer.Components.ActivityWrappers.V2; + +/// +/// A wrapper for an activity component. +/// +public partial class ActivityWrapper : ActivityWrapperBase; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/EmbeddedActivityWrapper.razor b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/EmbeddedActivityWrapper.razor new file mode 100644 index 0000000..2ead2d1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/EmbeddedActivityWrapper.razor @@ -0,0 +1,21 @@ +@inherits EmbeddedActivityWrapperBase +@{ + var colorStyle = IsSelected ? $"color: {Color};" : ""; +} + + + + @Label + + @if (!string.IsNullOrWhiteSpace(Description) && ShowDescription) + { + @Description + } + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/EmbeddedActivityWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/EmbeddedActivityWrapper.razor.cs new file mode 100644 index 0000000..14ba294 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/ActivityWrappers/V2/EmbeddedActivityWrapper.razor.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Workflows.Designer.Components.ActivityWrappers.V2; + +public partial class EmbeddedActivityWrapper; \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor b/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor new file mode 100644 index 0000000..49f21ea --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor @@ -0,0 +1,9 @@ +@inherits StudioComponentBase +@{ + var cssClass = "elsa-flowchart-diagram-designer" + (string.IsNullOrEmpty(Options.Value.DesignerCssClass) ? "" : " " + Options.Value.DesignerCssClass); +} + +
+
+
+
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor.cs b/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor.cs new file mode 100644 index 0000000..ebde09a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor.cs @@ -0,0 +1,416 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Workflows.Designer.Contracts; +using Elsa.Studio.Workflows.Designer.Interop; +using Elsa.Studio.Workflows.Designer.Models; +using Elsa.Studio.Workflows.Designer.Options; +using Elsa.Studio.Workflows.Designer.Services; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Extensions; +using Elsa.Studio.Workflows.UI.Args; +using Humanizer; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; +using MudBlazor.Utilities; +using ThrottleDebounce; + +namespace Elsa.Studio.Workflows.Designer.Components; + +/// +/// A Blazor component that renders a flowchart designer. +/// +public partial class FlowchartDesigner : IDisposable, IAsyncDisposable +{ + private readonly string _containerId = $"container-{Guid.NewGuid():N}"; + private DotNetObjectReference? _componentRef; + private IFlowchartMapper? _flowchartMapper; + private IActivityMapper? _activityMapper; + private X6GraphApi _graphApi = null!; + private readonly PendingActionsQueue _pendingGraphActions; + private readonly RateLimitedFunc _rateLimitedLoadFlowchartAction; + private IDictionary? _activityStats; + private JsonObject? _flowchart; + + /// + public FlowchartDesigner() + { + _pendingGraphActions = new(() => new(_graphApi != null!), () => Logger); + _rateLimitedLoadFlowchartAction = Debouncer.Debounce(async () => { await InvokeAsync(async () => await LoadFlowchartAsync(Flowchart, ActivityStats)); }, TimeSpan.FromMilliseconds(100)); + } + + /// The flowchart to render. + [Parameter] public JsonObject Flowchart { get; set; } = null!; + + /// The activity stats to render. + [Parameter] public IDictionary? ActivityStats { get; set; } + + /// Whether the flowchart is read-only. + [Parameter] public bool IsReadOnly { get; set; } + + /// An event raised when an activity is selected. + [Parameter] public EventCallback ActivitySelected { get; set; } + + [Parameter] public EventCallback ActivityPropsChanged { get; set; } + + /// An event raised when an activity-embedded port is selected. + [Parameter] public EventCallback ActivityEmbeddedPortSelected { get; set; } + + /// An event raised when an activity is double-clicked. + [Parameter] public EventCallback ActivityDoubleClick { get; set; } + + /// An event raised when the canvas is selected. + [Parameter] public EventCallback CanvasSelected { get; set; } + + /// An event raised when the graph is updated. + [Parameter] public EventCallback GraphUpdated { get; set; } + + [Inject] private DesignerJsInterop DesignerJsInterop { get; set; } = null!; + [Inject] private IThemeService ThemeService { get; set; } = null!; + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = null!; + [Inject] private IMapperFactory MapperFactory { get; set; } = null!; + [Inject] private IIdentityGenerator IdentityGenerator { get; set; } = null!; + [Inject] private IActivityNameGenerator ActivityNameGenerator { get; set; } = null!; + [Inject] private IOptions Options { get; set; } = null!; + [Inject] private ILogger Logger { get; set; } = null!; + + /// + /// Invoked from JavaScript when an activity is selected. + /// + /// The selected activity. + [JSInvokable] + public async Task HandleActivitySelected(JsonObject activity) + { + if (ActivitySelected.HasDelegate) + await ActivitySelected.InvokeAsync(activity); + } + + public async Task UpdateActivityAsync(JsonObject activity) + { + if (ActivityPropsChanged.HasDelegate) + await ActivityPropsChanged.InvokeAsync(activity); + } + + /// + /// Invoked from JavaScript when an activity embedded port is selected. + /// + /// The selected activity. + /// The selected port name. + [JSInvokable] + public async Task HandleActivityEmbeddedPortSelected(JsonObject activity, string portName) + { + if (ActivityEmbeddedPortSelected.HasDelegate) + { + var args = new ActivityEmbeddedPortSelectedArgs(activity, portName); + await ActivityEmbeddedPortSelected.InvokeAsync(args); + } + } + + /// + /// Invoked from JavaScript when an activity is double-clicked. + /// + /// The clicked activity. + [JSInvokable] + public async Task HandleActivityDoubleClick(JsonObject activity) + { + if (ActivityDoubleClick.HasDelegate) + { + await ActivityDoubleClick.InvokeAsync(activity); + } + } + + /// Invoked from JavaScript when the canvas is selected. + [JSInvokable] + public async Task HandleCanvasSelected() + { + if (CanvasSelected.HasDelegate) + await CanvasSelected.InvokeAsync(); + } + + /// Invoked from JavaScript when the graph is updated. + [JSInvokable] + public async Task HandleGraphUpdated() + { + if (GraphUpdated.HasDelegate) + await GraphUpdated.InvokeAsync(); + } + + /// Invoked from JavaScript when the graph is updated. + [JSInvokable] + public async Task HandlePasteCellsRequested(X6ActivityNode[] activityNodes, X6Edge[] edges) + { + var allActivities = Flowchart.GetActivities().ToList(); + var activityLookup = new Dictionary(); + var container = Flowchart; + + foreach (var activityNode in activityNodes) + { + var activity = activityNode.Data; + var activityType = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var descriptor = ActivityRegistry.Find(activityType, activityVersion)!; + var newActivityId = IdentityGenerator.GenerateId(); + var newName = ActivityNameGenerator.GenerateNextName(allActivities, descriptor); + + // Capture the original activity ID so we can update the edges. + activityLookup[activityNode.Id] = activityNode; + + // Update the activity ID and name. + activity.SetId(newActivityId); + activity.SetNodeId($"{container.GetNodeId()}:{newActivityId}"); + activity.SetName(newName); + activityNode.Id = newActivityId; + + // Add activity to the list of all activities. This is used to generate a new name for the next activity. + allActivities.Add(activity); + + // Update the activity metadata. + var designerMetadata = activity.GetDesignerMetadata(); + designerMetadata.Position.X = activityNode.Position.X + 64; + designerMetadata.Position.Y = activityNode.Position.Y + 64; + activityNode.Position.X = designerMetadata.Position.X; + activityNode.Position.Y = designerMetadata.Position.Y; + activity.SetDesignerMetadata(designerMetadata); + + // If the activity contains embedded ports, generate new IDs for the contained flowchart. + ProcessEmbeddedPorts(activity, descriptor); + } + + // Update the edges. + foreach (var edge in edges) + { + var sourceActivityId = edge.Source.Cell; + var targetActivityId = edge.Target.Cell; + var sourceActivity = activityLookup[sourceActivityId]; + var targetActivity = activityLookup[targetActivityId]; + + edge.Source.Cell = sourceActivity.Data.GetId(); + edge.Target.Cell = targetActivity.Data.GetId(); + } + + // Update the flowchart. + await ScheduleGraphActionAsync(async () => await _graphApi.PasteCellsAsync(activityNodes, edges)); + } + + /// + /// Reads the flowchart from the graph. + /// + /// The flowchart. + public async Task ReadFlowchartAsync() + { + var serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + return await ScheduleGraphActionAsync(async () => + { + var data = await _graphApi.ReadGraphAsync(); + var cells = data.GetProperty("cells").EnumerateArray(); + var nodes = cells.Where(x => x.GetProperty("shape").GetString() == "elsa-activity").Select(x => x.Deserialize(serializerOptions)!).ToList(); + var edges = cells.Where(x => x.GetProperty("shape").GetString() == "elsa-edge").Select(x => x.Deserialize(serializerOptions)!).ToList(); + var graph = new X6Graph(nodes, edges); + var flowchartMapper = await GetFlowchartMapperAsync(); + var exportedFlowchart = flowchartMapper.Map(graph); + var activities = exportedFlowchart.GetActivities(); + var connections = exportedFlowchart.GetConnections(); + + var flowchart = Flowchart; + flowchart.SetProperty(activities, "activities"); + flowchart.SetProperty(connections.SerializeToNode(), "connections"); + + return flowchart; + }); + } + + /// + /// Loads the flowchart into the graph. + /// + /// The flowchart to load. + /// The activity stats to load. + public async Task LoadFlowchartAsync(JsonObject activity, IDictionary? activityStats) + { + Flowchart = activity; + ActivityStats = activityStats; + var flowchartMapper = await GetFlowchartMapperAsync(); + var flowchart = activity.GetFlowchart(); + var graph = flowchartMapper.Map(flowchart, activityStats); + await ScheduleGraphActionAsync(() => _graphApi.LoadGraphAsync(graph)); + } + + /// + /// Adds an activity to the graph. + /// + /// The activity to add. + public async Task AddActivityAsync(JsonObject activity) + { + var mapper = await GetActivityMapperAsync(); + var node = mapper.MapActivity(activity); + await ScheduleGraphActionAsync(() => _graphApi.AddActivityNodeAsync(node)); + } + + /// + /// Selects the specified activity in the graph. + /// + /// The ID of the activity to select. + public async Task SelectActivityAsync(string id) + { + await ScheduleGraphActionAsync(() => _graphApi.SelectActivityAsync(id)); + } + + /// Zoom the canvas to fit all activities. + public async Task ZoomToFitAsync() => await ScheduleGraphActionAsync(() => _graphApi.ZoomToFitAsync()); + + /// + /// Center the canvas content. + /// + public async Task CenterContentAsync() => await ScheduleGraphActionAsync(() => _graphApi.CenterContentAsync()); + + /// Update the Graph Layout. + public async Task AutoLayoutAsync(JsonObject activity, IDictionary? activityStats) + { + var flowchartMapper = await GetFlowchartMapperAsync(); + var flowchart = activity.GetFlowchart(); + var graph = flowchartMapper.Map(flowchart, activityStats); + await ScheduleGraphActionAsync(() => _graphApi.AutoLayoutAsync(graph)); + } + + /// + /// Update the specified activity on the graph. + /// + /// The activity ID. + /// The updated activity. + public async Task UpdateActivityAsync(string id, JsonObject activity) => await ScheduleGraphActionAsync(() => _graphApi.UpdateActivityAsync(activity)); + + /// + /// Update the specified activity stats on the graph. + /// + /// The activity ID. + /// The updated activity stats. + public async Task UpdateActivityStatsAsync(string activityId, ActivityStats stats) => await ScheduleGraphActionAsync(() => DesignerJsInterop.UpdateActivityStatsAsync($"activity-{activityId}", activityId, stats)); + + /// + protected override void OnInitialized() + { + ThemeService.IsDarkModeChanged += OnDarkModeChanged; + _flowchart = Flowchart; + } + + /// + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _componentRef = DotNetObjectReference.Create(this); + _graphApi = await DesignerJsInterop.CreateGraphAsync(_containerId, _componentRef, IsReadOnly); + await _pendingGraphActions.ProcessAsync(); + } + } + + /// + protected override async Task OnParametersSetAsync() + { + if (!Equals(_flowchart, Flowchart) && _flowchart?.GetNodeId() != Flowchart.GetNodeId()) + { + _flowchart = Flowchart; + await _rateLimitedLoadFlowchartAction.InvokeAsync(); + } + + if (!Equals(_activityStats, ActivityStats)) + { + _activityStats = ActivityStats; + await _rateLimitedLoadFlowchartAction.InvokeAsync(); + } + } + + private async Task GetFlowchartMapperAsync() => _flowchartMapper ??= await MapperFactory.CreateFlowchartMapperAsync(); + private async Task GetActivityMapperAsync() => _activityMapper ??= await MapperFactory.CreateActivityMapperAsync(); + private async Task SetGridColorAsync(string color) => await ScheduleGraphActionAsync(() => _graphApi.SetGridColorAsync(color)); + private async Task ScheduleGraphActionAsync(Func action) => await _pendingGraphActions.EnqueueAsync(action); + private async Task ScheduleGraphActionAsync(Func> action) => await _pendingGraphActions.EnqueueAsync(action); + + private void GenerateNewActivityIds(JsonObject container) + { + var activities = container.GetActivities().ToList(); + var activityLookup = new Dictionary(); + var newContainerId = IdentityGenerator.GenerateId(); + + // Update the container ID. + container.SetId(newContainerId); + container.SetNodeId($"{container.GetNodeId()}:{newContainerId}"); + + foreach (var activity in activities) + { + var activityType = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var descriptor = ActivityRegistry.Find(activityType, activityVersion)!; + var newActivityId = IdentityGenerator.GenerateId(); + + // Capture the original activity ID so we can update the edges. + activityLookup[activity.GetId()] = activity; + + // Update the activity ID. + activity.SetId(newActivityId); + activity.SetNodeId($"{container.GetNodeId()}:{newActivityId}"); + + // If the activity contains embedded ports, generate new IDs for the contained flowchart. + ProcessEmbeddedPorts(activity, descriptor); + } + + // Update connections. + var connections = container.GetConnections().ToList(); + + foreach (var connection in connections) + { + var sourceActivityId = connection.Source.ActivityId; + var targetActivityId = connection.Target.ActivityId; + var sourceActivity = activityLookup[sourceActivityId]; + var targetActivity = activityLookup[targetActivityId]; + + connection.Source.ActivityId = sourceActivity.GetId(); + connection.Target.ActivityId = targetActivity.GetId(); + } + + container.SetConnections(connections); + } + + /// Processes each embedded port's activity and generates new IDs for the contained flowchart. + private void ProcessEmbeddedPorts(JsonObject activity, ActivityDescriptor descriptor) + { + var embeddedPorts = descriptor.Ports.Where(x => x.Type == PortType.Embedded); + foreach (var embeddedPort in embeddedPorts) + { + var camelName = embeddedPort.Name.Camelize(); + if (activity.TryGetPropertyValue(camelName, out var propValue) && propValue is JsonObject childActivity) + GenerateNewActivityIds(childActivity); + } + } + + private async void OnDarkModeChanged() + { + var palette = ThemeService.CurrentPalette; + var gridColor = palette.BackgroundGray; + await SetGridColorAsync(gridColor.ToString(MudColorOutputFormats.HexA)); + } + + async ValueTask IAsyncDisposable.DisposeAsync() + { + if (_graphApi != null!) + await _graphApi.DisposeGraphAsync(); + + ((IDisposable)this).Dispose(); + } + + void IDisposable.Dispose() + { + ThemeService.IsDarkModeChanged -= OnDarkModeChanged; + _componentRef?.Dispose(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IActivityMapper.cs b/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IActivityMapper.cs new file mode 100644 index 0000000..97a071e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IActivityMapper.cs @@ -0,0 +1,37 @@ +using System.Text.Json.Nodes; +using Elsa.Studio.Workflows.Designer.Models; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.Designer.Contracts; + +/// +/// Maps an Activity to an X6Node. +/// +public interface IActivityMapper +{ + /// + /// Maps an activity to an X6Node. + /// + /// The activity. + /// Activity stats. + X6ActivityNode MapActivity(JsonObject activity, ActivityStats? activityStats = null); + + /// + /// Gets the outbound ports for an activity. + /// + /// The activity. + IEnumerable GetOutPorts(JsonObject activity); + + /// + /// Gets the inbound ports for an activity. + /// + /// The activity. + IEnumerable GetInPorts(JsonObject activity); + + /// + /// Gets the inbound and outbound ports for an activity. + /// + /// The activity. + X6Ports GetPorts(JsonObject activity); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IFlowchartMapper.cs b/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IFlowchartMapper.cs new file mode 100644 index 0000000..4b73e7e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IFlowchartMapper.cs @@ -0,0 +1,26 @@ +using System.Text.Json.Nodes; +using Elsa.Studio.Workflows.Designer.Models; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.Designer.Contracts; + +/// +/// Maps a Flowchart activity from and to an X6Graph. +/// +public interface IFlowchartMapper +{ + /// + /// Maps a flowchart activity to an X6Graph. + /// + /// The flowchart activity. + /// A map of activity stats. + X6Graph Map(JsonObject flowchart, IDictionary? activityStatsMap = null); + + /// + /// Maps an X6 graph to a flowchart activity. + /// + /// The X6 graph. + JsonObject Map(X6Graph graph); + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IMapperFactory.cs b/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IMapperFactory.cs new file mode 100644 index 0000000..ee780f2 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Contracts/IMapperFactory.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Workflows.Designer.Contracts; + +internal interface IMapperFactory +{ + Task CreateFlowchartMapperAsync(CancellationToken cancellationToken = default); + Task CreateActivityMapperAsync(CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Elsa.Studio.Workflows.Designer.csproj b/src/modules/Elsa.Studio.Workflows.Designer/Elsa.Studio.Workflows.Designer.csproj new file mode 100644 index 0000000..721bdb1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Elsa.Studio.Workflows.Designer.csproj @@ -0,0 +1,30 @@ + + + + Adds workflow designer Blazor components powered by JS interop with X6. + elsa studio module x6 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Extensions/ComponentConfigurationExtensions.cs b/src/modules/Elsa.Studio.Workflows.Designer/Extensions/ComponentConfigurationExtensions.cs new file mode 100644 index 0000000..43185fa --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Extensions/ComponentConfigurationExtensions.cs @@ -0,0 +1,21 @@ +using Elsa.Studio.Workflows.Designer.Components.ActivityWrappers.V2; +using Microsoft.AspNetCore.Components.Web; + +namespace Elsa.Studio.Workflows.Designer.Extensions; + +/// +/// Contains extension methods for . +/// +public static class ComponentConfigurationExtensions +{ + /// + /// Registers custom elements. + /// + public static IJSComponentConfiguration RegisterCustomElsaStudioElements(this IJSComponentConfiguration configuration, Type? activityComponentType = null) + { + activityComponentType ??= typeof(ActivityWrapper); + configuration.RegisterForJavaScript(activityComponentType, "elsa-activity-wrapper", "registerBlazorCustomElement"); + + return configuration; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Workflows.Designer/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..3fc9848 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,18 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Designer.Contracts; +using Elsa.Studio.Workflows.Designer.Interop; +using Elsa.Studio.Workflows.Designer.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Elsa.Studio.Workflows.Designer.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddWorkflowsDesigner(this IServiceCollection services) + { + return services + .AddScoped() + .AddScoped() + .AddScoped(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/FodyWeavers.xml b/src/modules/Elsa.Studio.Workflows.Designer/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/FodyWeavers.xsd b/src/modules/Elsa.Studio.Workflows.Designer/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Interop/DesignerJsInterop.cs b/src/modules/Elsa.Studio.Workflows.Designer/Interop/DesignerJsInterop.cs new file mode 100644 index 0000000..59a0a6d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Interop/DesignerJsInterop.cs @@ -0,0 +1,70 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; +using Elsa.Studio.Workflows.Designer.Components; +using Elsa.Studio.Workflows.Designer.Options; +using Elsa.Studio.Workflows.Domain.Models; +using Microsoft.Extensions.Options; +using Microsoft.JSInterop; + +namespace Elsa.Studio.Workflows.Designer.Interop; + +/// +/// Provides access to the designer JavaScript module. +/// +public class DesignerJsInterop(IJSRuntime jsRuntime, IOptions options, IServiceProvider serviceProvider) : JsInteropBase(jsRuntime) +{ + protected override string ModuleName => "designer"; + + /// + /// Creates a new X6 graph object and returns its ID. + /// + /// The ID of the container element. + /// A reference to the component. + /// Whether the graph is read-only. + /// The ID of the graph. + public async ValueTask CreateGraphAsync(string containerId, DotNetObjectReference componentRef, bool isReadOnly = false) + { + return await TryInvokeAsync(async module => + { + var graphSettings = options.Value.GraphSettings; + await module.InvokeAsync("createGraph", containerId, componentRef, isReadOnly, graphSettings); + return new X6GraphApi(module, serviceProvider, containerId); + }); + } + + public async Task UpdateActivitySizeAsync(string elementId, JsonObject activity, Elsa.Api.Client.Shared.Models.Size? size = null) + { + var serializerOptions = GetSerializerOptions(); + var activityJson = JsonSerializer.Serialize(activity, serializerOptions); + await TryInvokeAsync(module => module.InvokeVoidAsync("updateActivitySize", elementId, activityJson, size)); + } + + public async Task UpdateActivityStatsAsync(string elementId, string activityId, ActivityStats stats) => + await TryInvokeAsync(module => module.InvokeVoidAsync("updateActivityStats", elementId, activityId, stats)); + + public async Task RaiseActivitySelectedAsync(string elementId, JsonObject activity) + { + var serializerOptions = GetSerializerOptions(); + var activityJson = JsonSerializer.Serialize(activity, serializerOptions); + await TryInvokeAsync(module => module.InvokeVoidAsync("raiseActivitySelected", elementId, activityJson)); + } + + public async Task RaiseActivityEmbeddedPortSelectedAsync(string elementId, JsonObject activity, string portName) + { + var serializerOptions = GetSerializerOptions(); + var activityJson = JsonSerializer.Serialize(activity, serializerOptions); + await TryInvokeAsync(module => module.InvokeVoidAsync("raiseActivityEmbeddedPortSelected", elementId, activityJson, portName)); + } + + private static JsonSerializerOptions GetSerializerOptions() + { + var serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + serializerOptions.Converters.Add(new JsonStringEnumConverter()); + return serializerOptions; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Interop/JsInteropBase.cs b/src/modules/Elsa.Studio.Workflows.Designer/Interop/JsInteropBase.cs new file mode 100644 index 0000000..903f4de --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Interop/JsInteropBase.cs @@ -0,0 +1,81 @@ +using Microsoft.JSInterop; + +namespace Elsa.Studio.Workflows.Designer.Interop; + +/// +/// Provides access to the designer JavaScript module. +/// +public abstract class JsInteropBase : IAsyncDisposable +{ + private readonly Lazy> _moduleTask; + + protected abstract string ModuleName { get; } + + /// Initializes a new instance of + protected JsInteropBase(IJSRuntime jsRuntime) + { + _moduleTask = new(() => jsRuntime.InvokeAsync("import", $"./_content/Elsa.Studio.Workflows.Designer/{ModuleName}.entry.js").AsTask()); + } + + public async ValueTask DisposeAsync() + { + if (_moduleTask.IsValueCreated) + { + var module = await _moduleTask.Value; + + try + { + await module.DisposeAsync(); + } + catch (JSDisconnectedException) + { + // This exception is thrown when the browser window is closed or the page reloads. + // We can safely ignore it. + } + } + } + + protected async Task InvokeAsync(Func func) + { + var module = await _moduleTask.Value; + await func(module); + } + + protected async Task TryInvokeAsync(Func func) + { + try + { + var module = await _moduleTask.Value; + await func(module); + } + catch (JSException) + { + // Ignore. + } + } + + protected async Task InvokeAsync(Func> func) + { + var module = await _moduleTask.Value; + return await func(module); + } + + protected async Task TryInvokeAsync(Func> func) + { + try + { + var module = await _moduleTask.Value; + return await func(module); + } + catch (JSException) + { + // Ignore. + } + catch(ObjectDisposedException) + { + // Ignore. + } + + return default!; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Interop/X6GraphApi.cs b/src/modules/Elsa.Studio.Workflows.Designer/Interop/X6GraphApi.cs new file mode 100644 index 0000000..c28d41f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Interop/X6GraphApi.cs @@ -0,0 +1,150 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; +using Elsa.Studio.Workflows.Designer.Contracts; +using Elsa.Studio.Workflows.Designer.Models; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; + +namespace Elsa.Studio.Workflows.Designer.Interop; + +/// Provides a wrapper around the X6 graph API. +public class X6GraphApi +{ + private readonly IJSObjectReference _module; + private readonly IServiceProvider _serviceProvider; + private readonly string _containerId; + + /// + /// Initializes a new instance of the class. + /// + /// The JavaScript module reference. + /// The service provider. + /// The ID of the container element. + public X6GraphApi(IJSObjectReference module, IServiceProvider serviceProvider, string containerId) + { + _module = module; + _serviceProvider = serviceProvider; + _containerId = containerId; + } + + /// + /// Reads the flowchart from the graph. + /// + /// The flowchart. + public async Task ReadGraphAsync() => await InvokeAsync(module => module.InvokeAsync("readGraph", _containerId)); + + /// Disposes the graph. + public async Task DisposeGraphAsync() => await TryInvokeAsync(module => module.InvokeVoidAsync("disposeGraph", _containerId)); + + /// + /// Sets the grid color. + /// + /// The color. + public async Task SetGridColorAsync(string color) => await InvokeAsync(module => module.InvokeVoidAsync("setGridColor", _containerId, color)); + + /// + /// Adds a node to the graph. + /// + /// The node. + public async Task AddActivityNodeAsync(X6ActivityNode node) + { + var serializerOptions = GetSerializerOptions(); + var nodeElement = JsonSerializer.SerializeToElement(node, serializerOptions); + + await InvokeAsync(module => module.InvokeVoidAsync("addActivityNode", _containerId, nodeElement)); + } + + /// + /// Selects the specified activity in the graph. + /// + /// The ID of the activity to select. + public async Task SelectActivityAsync(string id) + { + await InvokeAsync(module => module.InvokeVoidAsync("selectActivity", _containerId, id)); + } + + /// + /// Adds the specified activity nodes and edges to the graph. + /// + /// The activity nodes. + /// The edges. + public async Task PasteCellsAsync(IEnumerable activityNodes, X6Edge[] edges) + { + var serializerOptions = GetSerializerOptions(); + var activityNodeElements = JsonSerializer.SerializeToElement(activityNodes, serializerOptions); + var edgeElements = JsonSerializer.SerializeToElement(edges, serializerOptions); + await InvokeAsync(module => module.InvokeVoidAsync("pasteCells", _containerId, activityNodeElements, edgeElements)); + } + + /// + /// Loads the specified model into the graph. + /// + /// The model. + public async Task LoadGraphAsync(X6Graph graph) + { + var serializedGraph = SerializeGraph(graph); + await InvokeAsync(module => module.InvokeVoidAsync("loadGraph", _containerId, serializedGraph)); + } + + /// Zoom the canvas to fit the content. + public async Task ZoomToFitAsync() => await InvokeAsync(module => module.InvokeVoidAsync("zoomToFit", _containerId)); + + /// Center the canvas content. + public async Task CenterContentAsync() => await InvokeAsync(module => module.InvokeVoidAsync("centerContent", _containerId)); + + /// Adjusts the graph layout. + public async Task AutoLayoutAsync(X6Graph graph) + { + var serializedGraph = SerializeGraph(graph); + await InvokeAsync(module => module.InvokeVoidAsync("autoLayout", _containerId, serializedGraph)); + } + + /// + /// Updates the node with the specified activity. + /// + /// The activity. + public async Task UpdateActivityAsync(JsonObject activity) + { + var serializerOptions = GetSerializerOptions(); + var mapperFactory = _serviceProvider.GetRequiredService(); + var activityMapper = await mapperFactory.CreateActivityMapperAsync(); + var ports = activityMapper.GetPorts(activity); + var activityElement = JsonSerializer.SerializeToElement(activity, serializerOptions); + await InvokeAsync(module => module.InvokeVoidAsync("updateActivity", _containerId, activityElement, ports)); + } + + private async Task InvokeAsync(Func func) => await func(_module); + + private async Task TryInvokeAsync(Func func) + { + try + { + await func(_module); + } + catch (JSDisconnectedException) + { + // Ignore. + } + } + + private async Task InvokeAsync(Func> func) => await func(_module); + + // Serializing the graph here instead of relying on the JS interop layer to avoid the max depth of 32 exception. + private static string SerializeGraph(X6Graph graph) + { + var options = GetSerializerOptions(); + return JsonSerializer.Serialize(graph, options); + } + + private static JsonSerializerOptions GetSerializerOptions() + { + var serializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + serializerOptions.Converters.Add(new JsonStringEnumConverter()); + return serializerOptions; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6ActivityNode.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6ActivityNode.cs new file mode 100644 index 0000000..52286c4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6ActivityNode.cs @@ -0,0 +1,17 @@ +using System.Text.Json.Nodes; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6ActivityNode +{ + public string Id { get; set; } = null!; + public string Shape { get; set; } = null!; + public X6Position Position { get; set; } = null!; + public X6Size Size { get; set; } = null!; + public JsonObject Data { get; set; } = null!; + public X6Ports Ports { get; set; } = new(); + public ActivityStats? ActivityStats { get; set; } + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Attrs.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Attrs.cs new file mode 100644 index 0000000..103efde --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Attrs.cs @@ -0,0 +1,6 @@ +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6Attrs : Dictionary +{ + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Edge.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Edge.cs new file mode 100644 index 0000000..d32206a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Edge.cs @@ -0,0 +1,9 @@ +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6Edge +{ + public X6Endpoint Source { get; set; } = null!; + public X6Endpoint Target { get; set; } = null!; + public string? Shape { get; set; } + public X6Position[] Vertices { get; set; } = []; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Endpoint.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Endpoint.cs new file mode 100644 index 0000000..3bd0f42 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Endpoint.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6Endpoint +{ + public string Cell { get; set; } = null!; + public string Port { get; set; } = null!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Graph.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Graph.cs new file mode 100644 index 0000000..7115ae7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Graph.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6Graph +{ + [JsonConstructor] + public X6Graph() + { + } + + public X6Graph(IEnumerable nodes, IEnumerable edges) + { + Nodes = nodes.ToList(); + Edges = edges.ToList(); + } + + public ICollection Nodes { get; set; } = new List(); + public ICollection Edges { get; set; } = new List(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Port.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Port.cs new file mode 100644 index 0000000..cac8670 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Port.cs @@ -0,0 +1,10 @@ +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6Port +{ + public string Id { get; set; } = null!; + public string Group { get; set; } = null!; + public string? Type { get; set; } + public string? Position { get; set; } + public IDictionary? Attrs { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Ports.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Ports.cs new file mode 100644 index 0000000..1d2c439 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Ports.cs @@ -0,0 +1,6 @@ +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6Ports +{ + public ICollection Items { get; set; } = new List(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Position.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Position.cs new file mode 100644 index 0000000..64aa307 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Position.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6Position +{ + [JsonConstructor] + public X6Position() + { + } + + public X6Position(double x, double y) + { + X = x; + Y = y; + } + + public double X { get; set; } + public double Y { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Size.cs b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Size.cs new file mode 100644 index 0000000..2e4d1e9 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Models/X6Size.cs @@ -0,0 +1,20 @@ +using System.Text.Json.Serialization; + +namespace Elsa.Studio.Workflows.Designer.Models; + +public class X6Size +{ + [JsonConstructor] + public X6Size() + { + } + + public X6Size(double width, double height) + { + Width = width; + Height = height; + } + + public double Width { get; set; } + public double Height { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Module.cs b/src/modules/Elsa.Studio.Workflows.Designer/Module.cs new file mode 100644 index 0000000..7498b49 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Module.cs @@ -0,0 +1,8 @@ +using Elsa.Studio.Abstractions; + +namespace Elsa.Studio.Workflows.Designer; + +public class Feature : FeatureBase +{ + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Options/DesignerOptions.cs b/src/modules/Elsa.Studio.Workflows.Designer/Options/DesignerOptions.cs new file mode 100644 index 0000000..2ccb116 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Options/DesignerOptions.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Workflows.Designer.Options; + +public class DesignerOptions +{ + public string? DesignerCssClass { get; set; } = "elsa-flowchart-diagram-designer-v2"; + public X6GraphSettings GraphSettings { get; set; } = new(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Options/X6GraphSettings.cs b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6GraphSettings.cs new file mode 100644 index 0000000..d04c2bd --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6GraphSettings.cs @@ -0,0 +1,9 @@ +namespace Elsa.Studio.Workflows.Designer.Options; + +public class X6GraphSettings +{ + public X6Grid Grid { get; set; } = new(); + public double MagnetThreshold { get; set; } + public X6Panning Panning { get; set; } = new(); + public X6Mousewheel Mousewheel { get; set; } = new(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Grid.cs b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Grid.cs new file mode 100644 index 0000000..d912f55 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Grid.cs @@ -0,0 +1,9 @@ +namespace Elsa.Studio.Workflows.Designer.Options; + +public class X6Grid +{ + public string Type { get; set; } = "dot"; + public bool Visible { get; set; } = true; + public double Size { get; set; } = 20; + public object? Args { get; set; } = new X6GridArgs(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Options/X6GridArgs.cs b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6GridArgs.cs new file mode 100644 index 0000000..518ce88 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6GridArgs.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Workflows.Designer.Options; + +public class X6GridArgs +{ + public string Color { get; set; } = "#334154"; //f1f1f1 for V1 + public double Thickness { get; set; } = 1; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Mousewheel.cs b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Mousewheel.cs new file mode 100644 index 0000000..763b874 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Mousewheel.cs @@ -0,0 +1,9 @@ +namespace Elsa.Studio.Workflows.Designer.Options; + +public class X6Mousewheel +{ + public bool Enabled { get; set; } = true; + public double factor { get; set; } = 1.05; + public double MinScale { get; set; } = 0.4; + public double MaxScale { get; set; } = 3; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Panning.cs b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Panning.cs new file mode 100644 index 0000000..8b6bc24 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Options/X6Panning.cs @@ -0,0 +1,6 @@ +namespace Elsa.Studio.Workflows.Designer.Options; + +public class X6Panning +{ + public bool Enabled { get; set; } = true; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Services/ActivityMapper.cs b/src/modules/Elsa.Studio.Workflows.Designer/Services/ActivityMapper.cs new file mode 100644 index 0000000..69a7e4e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Services/ActivityMapper.cs @@ -0,0 +1,148 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Studio.Workflows.Designer.Contracts; +using Elsa.Studio.Workflows.Designer.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.Designer.Services; + +internal class ActivityMapper( + IActivityRegistry activityRegistry, + IActivityPortService activityPortService, + IActivityDisplaySettingsRegistry activityDisplaySettingsRegistry) + : IActivityMapper +{ + public X6ActivityNode MapActivity(JsonObject activity, ActivityStats? activityStats = null) + { + var activityId = activity.GetId(); + var designerMetadata = activity.GetDesignerMetadata(); + var position = designerMetadata.Position; + var size = designerMetadata.Size; + var x = position?.X ?? 0; + var y = position?.Y ?? 0; + var width = size?.Width ?? 0; + var height = size?.Height ?? 0; + + if (width == 0) width = 200; + if (height == 0) height = 50; + + // Create node. + var node = new X6ActivityNode + { + Id = activityId, + Data = activity, + Size = new X6Size(width, height), + Position = new X6Position(x, y), + Shape = "elsa-activity", + Ports = GetPorts(activity) + }; + + node.ActivityStats = activityStats; + + return node; + } + + public X6Ports GetPorts(JsonObject activity) + { + // Create input ports. + var inPorts = GetInPorts(activity); + + // Create output ports. + var outPorts = GetOutPorts(activity); + + // Concatenate input and output ports. + return new X6Ports + { + Items = inPorts.Concat(outPorts).ToList() + }; + } + + public IEnumerable GetOutPorts(JsonObject activity) + { + var activityType = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var activityDescriptor = activityRegistry.Find(activityType, activityVersion)!; + var sourcePorts = activityPortService.GetPorts(new PortProviderContext(activityDescriptor, activity)).Where(x => x.Type == PortType.Flow); + var displaySettings = activityDisplaySettingsRegistry.GetSettings(activity.GetTypeName()); + + var ports = sourcePorts.Select(sourcePort => new X6Port + { + Id = sourcePort.Name, + Group = "out", + Attrs = new X6Attrs + { + ["text"] = new X6Attrs + { + ["text"] = sourcePort.DisplayName ?? string.Empty + }, + ["circle"] = new X6Attrs + { + ["fill"] = displaySettings.Color, + } + } + }).ToList(); + + if (ports.All(port => port.Group != "out")) + { + // Create default output port, except for terminal nodes. + var isTerminalNode = activityDescriptor.IsTerminal; + + if (!isTerminalNode) + { + ports.Add(new X6Port + { + Id = "Done", + Group = "out", + Attrs = new X6Attrs + { + ["text"] = new X6Attrs + { + ["text"] = "Done" + }, + ["circle"] = new X6Attrs + { + ["fill"] = displaySettings.Color, + } + } + }); + } + } + + return ports; + } + + public IEnumerable GetInPorts(JsonObject activity) + { + var displaySettings = activityDisplaySettingsRegistry.GetSettings(activity.GetTypeName()); + var activityType = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var activityDescriptor = activityRegistry.Find(activityType, activityVersion)!; + + var ports = new List(); + // Create default output port, except for terminal nodes. + var isStart = activityDescriptor.IsStart; + if (!isStart) + { + // Create default input port. + ports.Add(new X6Port + { + Id = "In", + Group = "in", + Attrs = new X6Attrs + { + ["circle"] = new X6Attrs + { + ["stroke"] = displaySettings.Color, + } + } + }); + } + + return ports; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Services/FlowchartMapper.cs b/src/modules/Elsa.Studio.Workflows.Designer/Services/FlowchartMapper.cs new file mode 100644 index 0000000..827ce45 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Services/FlowchartMapper.cs @@ -0,0 +1,102 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Designer.Contracts; +using Elsa.Studio.Workflows.Designer.Models; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.Designer.Services; + +internal class FlowchartMapper(IActivityMapper activityMapper) : IFlowchartMapper +{ + public X6Graph Map(JsonObject flowchart, IDictionary? activityStatsMap = null) + { + var graph = new X6Graph(); + var activities = flowchart.GetActivities(); + var connections = flowchart.GetConnections(); + + foreach (var activity in activities) + { + var activityNodeId = activity.GetNodeId(); + var activityStats = activityStatsMap?.TryGetValue(activityNodeId, out var stats) == true ? stats : null; + var node = activityMapper.MapActivity(activity, activityStats); + graph.Nodes.Add(node); + } + + foreach (var connection in connections) + { + var source = connection.Source; + var target = connection.Target; + var sourceId = source.ActivityId; + var sourcePort = source.Port ?? "Done"; + var targetId = target.ActivityId; + var targetPort = target.Port ?? "In"; + var connector = new X6Edge + { + Shape = "elsa-edge", + Source = new() + { + Cell = sourceId, + Port = sourcePort + }, + Target = new() + { + Cell = targetId, + Port = targetPort + }, + Vertices = connection.Vertices.Select(x => new X6Position(x.X, x.Y)).ToArray() + }; + + graph.Edges.Add(connector); + } + + return graph; + } + + public JsonObject Map(X6Graph graph) + { + var activities = new List(); + var connections = new List(); + + foreach (var node in graph.Nodes) + { + var activity = node.Data; + var designerMetadata = activity.GetDesignerMetadata(); + + designerMetadata.Position = new() + { + X = node.Position.X, + Y = node.Position.Y + }; + + designerMetadata.Size = new() + { + Width = node.Size.Width, + Height = node.Size.Height + }; + + activity.SetDesignerMetadata(designerMetadata); + activities.Add(activity); + } + + foreach (var edge in graph.Edges) + { + var connection = new Connection + { + Source = new(edge.Source.Cell, edge.Source.Port), + Target = new(edge.Target.Cell, edge.Target.Port), + Vertices = edge.Vertices.Select(x => new Position(x.X, x.Y)).ToArray(), + }; + connections.Add(connection); + } + + var flowchart = new JsonObject(new Dictionary + { + ["activities"] = activities.SerializeToArray(), + ["connections"] = connections.SerializeToArray() + }); + + return flowchart; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Services/MapperFactory.cs b/src/modules/Elsa.Studio.Workflows.Designer/Services/MapperFactory.cs new file mode 100644 index 0000000..2314988 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Services/MapperFactory.cs @@ -0,0 +1,20 @@ +using Elsa.Studio.Workflows.Designer.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.UI.Contracts; + +namespace Elsa.Studio.Workflows.Designer.Services; + +internal class MapperFactory(IActivityRegistry activityRegistry, IActivityPortService activityPortService, IActivityDisplaySettingsRegistry activityDisplaySettingsRegistry) : IMapperFactory +{ + public async Task CreateFlowchartMapperAsync(CancellationToken cancellationToken = default) + { + var activityMapper = await CreateActivityMapperAsync(cancellationToken); + return new FlowchartMapper(activityMapper); + } + + public async Task CreateActivityMapperAsync(CancellationToken cancellationToken = default) + { + await activityRegistry.EnsureLoadedAsync(cancellationToken); + return new ActivityMapper(activityRegistry, activityPortService, activityDisplaySettingsRegistry); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Services/PendingActionsQueue.cs b/src/modules/Elsa.Studio.Workflows.Designer/Services/PendingActionsQueue.cs new file mode 100644 index 0000000..4adc533 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/Services/PendingActionsQueue.cs @@ -0,0 +1,72 @@ +using Microsoft.Extensions.Logging; + +namespace Elsa.Studio.Workflows.Designer.Services; + +/// +/// A queue for pending actions that can be processed in a FIFO manner. +/// +public class PendingActionsQueue(Func> shortCircuit, Func logger) +{ + private readonly Queue> _pendingActions = new(); + + /// + /// Processes all pending actions. + /// + public async Task ProcessAsync() + { + while (_pendingActions.Any()) + { + var action = _pendingActions.Dequeue(); + await TryExecuteActionAsync(action); + } + } + + /// + /// Enqueues an action to be executed. + /// + public async Task EnqueueAsync(Func action) + { + if(await shortCircuit()) + { + await TryExecuteActionAsync(action); + return; + } + + var tsc = new TaskCompletionSource(); + _pendingActions.Enqueue(async () => + { + await action(); + tsc.SetResult(); + }); + await tsc.Task; + } + + /// + /// Enqueues an action to be executed. + /// + public async Task EnqueueAsync(Func> action) + { + if(await shortCircuit()) + return await action(); + + var tsc = new TaskCompletionSource(); + _pendingActions.Enqueue(async () => + { + var result = await action(); + tsc.SetResult(result); + }); + return await tsc.Task; + } + + private async Task TryExecuteActionAsync(Func action) + { + try + { + await action(); + } + catch(Exception ex) + { + logger().LogWarning(ex, "An error occurred while executing a pending action."); + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows.Designer/_Imports.razor b/src/modules/Elsa.Studio.Workflows.Designer/_Imports.razor new file mode 100644 index 0000000..1704912 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows.Designer/_Imports.razor @@ -0,0 +1,4 @@ +@using Microsoft.AspNetCore.Components.Web +@using Elsa.Studio.Components +@using Elsa.Studio.Localization +@using MudBlazor \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityPicker.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityPicker.razor new file mode 100644 index 0000000..c6137b6 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityPicker.razor @@ -0,0 +1,68 @@ +@using Elsa.Studio.Workflows.Services +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Resources.ActivityDescriptors.Models +@using System.Text.Json.Nodes +@using System.Text.Json +@using Elsa.Studio.Workflows.Domain.Contracts +@using Elsa.Studio.Workflows.Models +@using Elsa.Studio.Workflows.UI.Contracts +@inherits StudioComponentBase +@using Microsoft.Extensions.Localization +@inject ILocalizer Localizer + + + + + + + + + + + @foreach (var grouping in GroupedActivityDescriptors.OrderBy(x => x.Key)) + { + var activityDescriptors = grouping.OrderBy(x => x.DisplayName ?? x.Name).ToList(); + var category = grouping.Key; + + + + @foreach (var activityDescriptor in activityDescriptors) + { + var displaySettings = ActivityDisplaySettingsRegistry.GetSettings(activityDescriptor.TypeName); + var icon = displaySettings.Icon; + var color = displaySettings.Color; + + + + + @if (icon != null) + { + + } + @(Localizer[activityDescriptor.DisplayName ?? activityDescriptor.Name]) + + + + } + + + } + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityPicker.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityPicker.razor.cs new file mode 100644 index 0000000..3154eed --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityPicker.razor.cs @@ -0,0 +1,72 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Extensions; +using Elsa.Studio.Workflows.Domain.Notifications; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.Services; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Localization; +using System.Globalization; +using System.Resources; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components; + +/// +/// A component that allows the user to pick an activity. +/// +public partial class ActivityPicker +{ + private string _searchText = ""; + + private IEnumerable> GroupedActivityDescriptors + { + get + { + if (string.IsNullOrWhiteSpace(_searchText)) + return ActivityDescriptors.GroupBy(x => x.Category); // Return all items grouped by category + + var items = ActivityDescriptors.Where(item => + item.Name.Contains(_searchText, StringComparison.InvariantCultureIgnoreCase) || + item.TypeName.Contains(_searchText, StringComparison.InvariantCultureIgnoreCase) || + (item.DisplayName != null && item.DisplayName.Contains(_searchText, StringComparison.InvariantCultureIgnoreCase)) || + item.Category.Contains(_searchText, StringComparison.InvariantCultureIgnoreCase) || + (item.Description != null && item.Description.Contains(_searchText, StringComparison.InvariantCultureIgnoreCase)) + ); + return items + .GroupBy(x => x.Category); + } + } + + /// + /// The drag and drop manager. + /// + [CascadingParameter] public DragDropManager DragDropManager { get; set; } = default!; + + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = default!; + [Inject] private IActivityDisplaySettingsRegistry ActivityDisplaySettingsRegistry { get; set; } = default!; + [Inject] private IMediator Mediator { get; set; } = default!; + + private IEnumerable ActivityDescriptors { get; set; } = new List(); + + /// + protected override async Task OnInitializedAsync() + { + await Refresh(); + } + + private async Task Refresh() + { + await ActivityRegistry.EnsureLoadedAsync(); + ActivityDescriptors = ActivityRegistry.ListBrowsable(); + StateHasChanged(); + } + + private void OnDragStart(ActivityDescriptor activityDescriptor) + { + DragDropManager.Payload = activityDescriptor; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/ActivityPropertiesPanel.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/ActivityPropertiesPanel.razor new file mode 100644 index 0000000..b93fac0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/ActivityPropertiesPanel.razor @@ -0,0 +1,134 @@ +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs.Outputs.Components +@using Elsa.Studio.Extensions +@using Variant = MudBlazor.Variant +@inherits StudioComponentBase +@inject ILocalizer Localizer + + + + + + @if (ActivityDescriptor?.Inputs.Any(x => x.IsBrowsable != false) == true) + { + + + + } + else + { + + @Localizer["This activity does not have any input properties."] + + } + + + + @if (ActivityDescriptor?.Outputs.Any(x => x.IsBrowsable != false) == true) + { + + + + } + else + { + + @Localizer["This activity does not have any output properties."] + + } + + + + @if (Activity != null && ActivityDescriptor != null) + { + + + + } + else + { + + @Localizer["This activity does not have any common properties."] + + } + + + + @if (Activity != null) + { + + + + } + else + { + + @Localizer["This activity does not have any common properties."] + + } + + + @if (IsTaskActivity) + { + + + + + + } + + + + + + + + + + @if (ActivityDescriptor != null) + { + + + + } + + + @if (IsWorkflowAsActivity) + { + + + + + + } + + @if (DisplayResilienceTab) + { + + + + + + } + + @foreach (var tab in PluginTabs) + { + + + @tab.Render((new { WorkflowDefinition, Activity, ActivityDescriptor, OnActivityUpdated }).ToDictionary()) + + + } + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/ActivityPropertiesPanel.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/ActivityPropertiesPanel.razor.cs new file mode 100644 index 0000000..bb7aa15 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/ActivityPropertiesPanel.razor.cs @@ -0,0 +1,67 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties; + +/// +/// Renders the properties of an activity. +/// +public partial class ActivityPropertiesPanel +{ + /// + /// Gets or sets the workflow definition. + /// + [Parameter] + public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// + /// Gets or sets the activity. + /// + [Parameter] + public JsonObject? Activity { get; set; } + + /// + /// Gets or sets the activity descriptor. + /// + [Parameter] + public ActivityDescriptor? ActivityDescriptor { get; set; } + + /// + /// Gets or sets a callback that is invoked when the activity is updated. + /// + [Parameter] + public Func? OnActivityUpdated { get; set; } + + /// + /// Gets or sets the visible pane height. + /// + [Parameter] + public int VisiblePaneHeight { get; set; } + + [Inject] private IExpressionService ExpressionService { get; set; } = null!; + + [Inject] private IEnumerable PluginTabs { get; set; } = new List(); + [Inject] private IRemoteFeatureProvider RemoteFeatureProvider { get; set; } = null!; + + private ExpressionDescriptorProvider ExpressionDescriptorProvider { get; } = new(); + private bool IsResilienceEnabled { get; set; } + private bool IsResilientActivity => ActivityDescriptor?.CustomProperties.TryGetValue("Resilient", out var resilientObj) == true && resilientObj.ConvertTo(); + private bool DisplayResilienceTab => IsResilienceEnabled && IsResilientActivity; + + /// + protected override async Task OnInitializedAsync() + { + var descriptors = await ExpressionService.ListDescriptorsAsync(); + IsResilienceEnabled = await RemoteFeatureProvider.IsEnabledAsync("Elsa.Resilience"); + ExpressionDescriptorProvider.AddRange(descriptors); + } + + private bool IsWorkflowAsActivity => ActivityDescriptor != null && ActivityDescriptor.CustomProperties.TryGetValue("RootType", out var value) && value.ConvertTo() == "WorkflowDefinitionActivity"; + private bool IsTaskActivity => ActivityDescriptor?.Kind == ActivityKind.Task; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Models.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Models.cs new file mode 100644 index 0000000..9574770 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Models.cs @@ -0,0 +1,5 @@ +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties; + +public record ActivityInputDisplayModel(RenderFragment Editor); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommitStrategyTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommitStrategyTab.razor new file mode 100644 index 0000000..964c279 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommitStrategyTab.razor @@ -0,0 +1,21 @@ +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Resources.CommitStrategies.Models +@inject ILocalizer Localizer + + + + @foreach (var commitStrategy in _commitStrategies) + { + @(commitStrategy?.DisplayName ?? Localizer["Default"]) + } + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommitStrategyTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommitStrategyTab.razor.cs new file mode 100644 index 0000000..d6a832d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommitStrategyTab.razor.cs @@ -0,0 +1,48 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.CommitStrategies.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs; + +/// +/// The Task tab for an activity. +/// +public partial class CommitStrategyTab +{ + /// The activity. + [Parameter] public JsonObject? Activity { get; set; } + + /// An event raised when the activity is updated. + [Parameter] public Func? OnActivityUpdated { get; set; } + [CascadingParameter] private IWorkspace? Workspace { get; set; } + [Inject] private ICommitStrategiesProvider CommitStrategiesProvider { get; set; } = null!; + private bool IsReadOnly => Workspace?.IsReadOnly == true; + private ICollection _commitStrategies = []; + private CommitStrategyDescriptor? _selectedCommitStrategy; + + /// + protected override async Task OnInitializedAsync() + { + var commitStrategies = (await CommitStrategiesProvider.GetActivityCommitStrategiesAsync()).ToList(); + commitStrategies.Insert(0, null!); + _commitStrategies = commitStrategies!; + _selectedCommitStrategy = _commitStrategies.FirstOrDefault(x => x?.Name == Activity!.GetCommitStrategy()); + await base.OnInitializedAsync(); + } + + private async Task RaiseActivityUpdated() + { + if (OnActivityUpdated != null) + await OnActivityUpdated(Activity!); + } + + private async Task OnCommitStrategySelectionChanged(CommitStrategyDescriptor? value) + { + _selectedCommitStrategy = value; + Activity!.SetCommitStrategy(value?.Name); + await RaiseActivityUpdated(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommonTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommonTab.razor new file mode 100644 index 0000000..7d69f52 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommonTab.razor @@ -0,0 +1,83 @@ +@using Elsa.Studio.Workflows.Services +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Extensions +@inherits StudioComponentBase +@using Microsoft.Extensions.Localization +@inject ILocalizer Localizer + +
+ @if (Activity != null && ActivityDescriptor != null) + { + + + + @Activity.GetId() + + + + + + + + + + + + + + + + + + + } +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommonTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommonTab.razor.cs new file mode 100644 index 0000000..fea16d1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/CommonTab.razor.cs @@ -0,0 +1,67 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs; + +/// The common tab for an activity. +public partial class CommonTab +{ + /// The activity. + [Parameter] public JsonObject? Activity { get; set; } + + /// The activity descriptor. + [Parameter] public ActivityDescriptor? ActivityDescriptor { get; set; } + + /// An event raised when the activity is updated. + [Parameter] public Func? OnActivityUpdated { get; set; } + [CascadingParameter] private IWorkspace? Workspace { get; set; } + + private bool IsTrigger => ActivityDescriptor?.Kind == ActivityKind.Trigger; + private bool IsReadOnly => Workspace?.IsReadOnly == true; + + private async Task OnActivityIdChanged(string value) + { + Activity!.SetId(value); + await RaiseActivityUpdated(); + } + + private async Task RaiseActivityUpdated() + { + if (OnActivityUpdated != null) + await OnActivityUpdated(Activity!); + } + + private async Task OnActivityNameChanged(string value) + { + Activity!.SetName(value); + await RaiseActivityUpdated(); + } + + private async Task OnActivityDisplayTextChanged(string value) + { + Activity!.SetDisplayText(value); + await RaiseActivityUpdated(); + } + + private async Task OnActivityDescriptionChanged(string value) + { + Activity!.SetDescription(value); + await RaiseActivityUpdated(); + } + + private async Task OnShowDescriptionChanged(bool? value) + { + Activity!.SetShowDescription(value == true); + await RaiseActivityUpdated(); + } + + private async Task OnCanStartWorkflowChanged(bool? value) + { + Activity!.SetCanStartWorkflow(value == true); + await RaiseActivityUpdated(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InfoTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InfoTab.razor new file mode 100644 index 0000000..679d9a3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InfoTab.razor @@ -0,0 +1,5 @@ +@inject ILocalizer Localizer + + @Localizer["Information"] + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InfoTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InfoTab.razor.cs new file mode 100644 index 0000000..b6f48b5 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InfoTab.razor.cs @@ -0,0 +1,31 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs; + +/// +/// The info tab for an activity. +/// +public partial class InfoTab +{ + /// + /// The activity descriptor. + /// + [Parameter] + public ActivityDescriptor ActivityDescriptor { get; set; } = default!; + + private DataPanelModel ActivityInfo { get; } = new(); + + /// + protected override void OnParametersSet() + { + ActivityDescriptor.ConstructionProperties.TryGetValue("WorkflowDefinitionId", out var link); + + ActivityInfo.Clear(); + + ActivityInfo.Add(Localizer["Type"], ActivityDescriptor.TypeName, link == null ? null : $"/workflows/definitions/{link}/edit"); + ActivityInfo.Add(Localizer["Description"], ActivityDescriptor.Description); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor new file mode 100644 index 0000000..8112b9c --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor @@ -0,0 +1,10 @@ +@inherits StudioComponentBase + + + + @foreach (var inputModel in InputDisplayModels) + { + @inputModel.Editor + } + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor.cs new file mode 100644 index 0000000..91e8aee --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor.cs @@ -0,0 +1,228 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptorOptions.Contracts; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; +using ThrottleDebounce; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs; + +/// +/// A tab for editing the inputs of an activity. +/// +public partial class InputsTab +{ + private readonly RateLimitedFunc>> _rateLimitedBuildInputEditorModelsAsync; + + /// + public InputsTab() + { + _rateLimitedBuildInputEditorModelsAsync = Debouncer.Debounce(BuildInputEditorModels, TimeSpan.FromMilliseconds(50), true); + } + + /// + /// Gets or sets the workflow definition. + /// + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// + /// Gets or sets the activity to edit. + /// + [Parameter] public JsonObject? Activity { get; set; } + + /// + /// Gets or sets the activity descriptor. + /// + [Parameter] public ActivityDescriptor? ActivityDescriptor { get; set; } + + /// + /// An event that is invoked when the activity is updated. + /// + [Parameter] public Func? OnActivityUpdated { get; set; } + + [CascadingParameter] private IWorkspace? Workspace { get; set; } + [CascadingParameter] private ExpressionDescriptorProvider ExpressionDescriptorProvider { get; set; } = null!; + [Inject] private IUIHintService UIHintService { get; set; } = null!; + + [Inject] private IBackendApiClientProvider BackendApiClientProvider { get; set; } = null!; + private ICollection InputDescriptors { get; set; } = new List(); + private ICollection OutputDescriptors { get; set; } = new List(); + private ICollection InputDisplayModels { get; set; } = new List(); + + /// + protected override async Task OnParametersSetAsync() + { + if (Activity == null || ActivityDescriptor == null) + return; + + InputDescriptors = ActivityDescriptor.Inputs.ToList(); + OutputDescriptors = ActivityDescriptor.Outputs.ToList(); + + var task = _rateLimitedBuildInputEditorModelsAsync.Invoke(); + if (task != null) InputDisplayModels = (await task).ToList(); + } + + private Task> BuildInputEditorModels() + { + return BuildInputEditorModels(Activity!, ActivityDescriptor!, InputDescriptors); + } + + private async Task> BuildInputEditorModels(JsonObject activity, ActivityDescriptor activityDescriptor, ICollection inputDescriptors) + { + var models = new List(); + var browsableInputDescriptors = inputDescriptors.Where(x => x.IsBrowsable == true).OrderBy(x => x.Order).ToList(); + + foreach (var inputDescriptor in browsableInputDescriptors) + { + var inputName = inputDescriptor.Name.Camelize(); + var value = activity.GetProperty(inputName); + var wrappedInput = inputDescriptor.IsWrapped ? ToWrappedInput(value) : null; + var syntaxProvider = wrappedInput != null ? GetSyntaxProvider(wrappedInput, inputDescriptor) : null; + + // Check if refresh is needed. + if (inputDescriptor.UISpecifications != null + && inputDescriptor.UISpecifications.TryGetValue("Refresh", out var refreshInput) + && bool.Parse(refreshInput.ToString()!)) + { + await RefreshDescriptor(activity, activityDescriptor, inputDescriptors, inputDescriptor); + } + + var uiHintHandler = UIHintService.GetHandler(inputDescriptor.UIHint); + object? input = inputDescriptor.IsWrapped ? wrappedInput : value; + + var context = new DisplayInputEditorContext + { + WorkflowDefinition = WorkflowDefinition!, + Activity = activity, + ActivityDescriptor = activityDescriptor, + InputDescriptor = inputDescriptor, + Value = input, + SelectedExpressionDescriptor = syntaxProvider, + UIHintHandler = uiHintHandler, + IsReadOnly = (Workspace?.IsReadOnly ?? false) || (inputDescriptor.IsReadOnly ?? false), + }; + + context.OnValueChanged = async v => await HandleValueChangedAsync(context, v); + var editor = uiHintHandler.DisplayInputEditor(context); + models.Add(new(editor)); + } + + return models; + } + + private async Task RefreshDescriptor(JsonObject activity, ActivityDescriptor activityDescriptor, IEnumerable inputDescriptors, InputDescriptor currentInputDescriptor) + { + try + { + var activityTypeName = activityDescriptor.TypeName; + var propertyName = currentInputDescriptor.Name; + + // Embed all props value in the context. + var contextDictionary = new Dictionary(); + foreach (var inputDescriptor in inputDescriptors) + { + var inputName = inputDescriptor.Name.Camelize(); + var value = activity.GetProperty(inputName); + if (value != null) + contextDictionary.Add(inputName, value); + } + + var api = await BackendApiClientProvider.GetApiAsync(); + + var result = await api.GetAsync(activityTypeName, propertyName, new() + { + Context = contextDictionary + }); + + currentInputDescriptor.UISpecifications = result.Items; + + // After refreshing, update the UI for any affected inputs + await UpdateInputDisplayModelsAsync(activity, activityDescriptor, inputDescriptors.ToList(), currentInputDescriptor); + } + catch (Exception) + { + // If an error occurs during refresh, we still want to keep the application running + // Errors might happen if backend is unavailable or returns an error response + // We could log the error here or show a notification, but for now we'll just silently continue + } + } + + private bool _isRefreshingModels; + + private async Task UpdateInputDisplayModelsAsync(JsonObject activity, ActivityDescriptor activityDescriptor, ICollection inputDescriptors, InputDescriptor refreshedInputDescriptor) + { + if (_isRefreshingModels) + return; + + try + { + _isRefreshingModels = true; + + // Rebuild all models + InputDisplayModels = (await BuildInputEditorModels(activity, activityDescriptor, inputDescriptors)).ToList(); + + // Force UI refresh + StateHasChanged(); + } + finally + { + _isRefreshingModels = false; + } + } + + private static WrappedInput? ToWrappedInput(object? value) + { + var converterOptions = new ObjectConverterOptions(serializerOptions => { serializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }); + + return value.ConvertTo(converterOptions); + } + + private async Task HandleValueChangedAsync(DisplayInputEditorContext context, object? value) + { + var activity = context.Activity; + var inputDescriptor = context.InputDescriptor; + + if (inputDescriptor.IsWrapped) + { + var wrappedInput = (WrappedInput)value!; + var syntaxProvider = ExpressionDescriptorProvider.GetByType(wrappedInput.Expression.Type); + context.SelectedExpressionDescriptor = syntaxProvider; + } + + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + var propName = inputDescriptor.Name.Camelize(); + activity.SetProperty(value?.SerializeToNode(options), propName); + + if (OnActivityUpdated != null) + await OnActivityUpdated(activity); + + //await InvokeAsync(StateHasChanged); + } + + private ExpressionDescriptor? GetSyntaxProvider(WrappedInput wrappedInput, InputDescriptor inputDescriptor) + { + // Safely read UIHint + var uiHint = inputDescriptor.UIHint; + + // If this is the code editor scenario and we have a DefaultSyntax, use that + if (uiHint.Equals("code-editor", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(inputDescriptor.DefaultSyntax)) + return ExpressionDescriptorProvider.GetByType(inputDescriptor.DefaultSyntax); + + // Otherwise fall back to the wrapped expression's type—but guard null + var exprType = wrappedInput?.Expression?.Type; + return string.IsNullOrEmpty(exprType) ? null : ExpressionDescriptorProvider.GetByType(exprType); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/LogPersistenceTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/LogPersistenceTab.razor new file mode 100644 index 0000000..225d974 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/LogPersistenceTab.razor @@ -0,0 +1,123 @@ +@using Elsa.Api.Client.Extensions +@using Elsa.Api.Client.Resources.ActivityDescriptors.Models +@using Elsa.Api.Client.Resources.Scripting.Models +@using Elsa.Api.Client.Shared.Models +@using Variant = MudBlazor.Variant +@inherits StudioComponentBase +@inject ILocalizer Localizer + +@{ + RenderFragment RenderSelectComponent( + string label, + PropertyDescriptor? propertyDescriptor, + LogPersistenceConfiguration? logPersistenceConfig, + EventCallback onExpressionChanged, + EventCallback onStrategyTypeChanged) + { + var expression = logPersistenceConfig?.Expression; + var strategyType = logPersistenceConfig?.StrategyType; + var props = GetExpressionEditorProps(propertyDescriptor); + var activityId = Activity?.GetNodeId() ?? "default"; + var key = activityId; + + return @ + + @foreach (var descriptor in _logPersistenceStrategyDescriptors) + { + @Localizer[descriptor.DisplayName] + } + + ; + } +} +
+ + + @Localizer["Default Configuration"] + @RenderSelectComponent( + @Localizer["Default Strategy"], + null, + _persistenceConfiguration.Default, + EventCallback.Factory.Create(this, OnDefaultExpressionChanged), + EventCallback.Factory.Create(this, OnDefaultStrategyChanged) + ) + + @Localizer["Internal State"] + @RenderSelectComponent( + @Localizer["Internal State"], + null, + _persistenceConfiguration.InternalState, + EventCallback.Factory.Create(this, OnInternalStateExpressionChanged), + EventCallback.Factory.Create(this, OnInternalStateStrategyChanged) + ) + + @Localizer["Input Properties"] + @if (!InputDescriptors.Any()) + { + + + @Localizer["This activity does not have any input properties."] + + + } + else + { + foreach (var input in InputDescriptors) + { + var config = GetLogPersistenceConfig(input.Name, _persistenceConfiguration.Inputs); + @RenderSelectComponent( + input.Name, + input, + config, + EventCallback.Factory.Create(this, expr => OnPropertyExpressionChanged(input.Name, _persistenceConfiguration.Inputs, expr)), + EventCallback.Factory.Create(this, value => OnPropertyStrategyChanged(input.Name, _persistenceConfiguration.Inputs, value))) + } + } + + + @Localizer["Output Properties"] + @if (!OutputDescriptors.Any()) + { + + + @Localizer["This activity does not have any output properties."] + + + } + else + { + foreach (var output in OutputDescriptors) + { + var config = GetLogPersistenceConfig(output.Name, _persistenceConfiguration.Outputs); + @RenderSelectComponent( + output.Name, + output, + config, + EventCallback.Factory.Create(this, expr => OnPropertyExpressionChanged(output.Name, _persistenceConfiguration.Outputs, expr)), + EventCallback.Factory.Create(this, value => OnPropertyStrategyChanged(output.Name, _persistenceConfiguration.Outputs, value))) + } + } + + +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/LogPersistenceTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/LogPersistenceTab.razor.cs new file mode 100644 index 0000000..32e2844 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/LogPersistenceTab.razor.cs @@ -0,0 +1,313 @@ +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Enums; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.LogPersistenceStrategies; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Serialization; +using Elsa.Api.Client.Shared.Enums; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Contracts; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs; + +/// +/// Represents the persistence tab. +/// +public partial class LogPersistenceTab +{ + /// An event raised when the activity is updated. + [Parameter] public Func? OnActivityUpdated { get; set; } + + /// + /// Gets or sets the workflow definition. + /// + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// + /// Gets or sets the activity to edit. + /// + [Parameter] public JsonObject? Activity { get; set; } + + /// + /// The workspace. + /// + [CascadingParameter] public IWorkspace? Workspace { get; set; } + + /// + /// Gets or sets the activity descriptor. + /// + [Parameter] public ActivityDescriptor? ActivityDescriptor { get; set; } + + [Inject] private ILogPersistenceStrategyService LogPersistenceStrategyService { get; set; } = null!; + + private ICollection InputDescriptors { get; set; } = new List(); + private ICollection OutputDescriptors { get; set; } = new List(); + private bool IsReadOnly => Workspace?.IsReadOnly == true; + private LegacyPersistenceActivityConfiguration _legacyPersistenceConfiguration = new(); + private PersistenceActivityConfiguration _persistenceConfiguration = new(); + private ICollection _logPersistenceStrategyDescriptors = new List(); + private const string LogPersistenceModeKey = "logPersistenceMode"; + private const string LogPersistenceConfigKey = "logPersistenceConfig"; + + /// + protected override async Task OnInitializedAsync() + { + _legacyPersistenceConfiguration = new(); + _persistenceConfiguration = new(); + _logPersistenceStrategyDescriptors = (await LogPersistenceStrategyService.GetLogPersistenceStrategiesAsync()).ToList(); + } + + /// + protected override void OnParametersSet() + { + if (Activity == null || ActivityDescriptor == null) + return; + + InputDescriptors = ActivityDescriptor.Inputs.ToList(); + OutputDescriptors = ActivityDescriptor.Outputs.ToList(); + + SetPersistenceProperties(); + } + + private async Task OnDefaultStrategyChanged(string? value) + { + _persistenceConfiguration.Default = new() + { + EvaluationMode = LogPersistenceEvaluationMode.Strategy, + StrategyType = value + }; + await PersistLogPersistenceStrategies(); + } + + private async Task OnDefaultExpressionChanged(Expression? expression) + { + _persistenceConfiguration.Default = new() + { + EvaluationMode = LogPersistenceEvaluationMode.Expression, + Expression = expression + }; + await PersistLogPersistenceStrategies(); + } + + private async Task OnInternalStateStrategyChanged(string? value) + { + _persistenceConfiguration.InternalState = new() + { + EvaluationMode = LogPersistenceEvaluationMode.Strategy, + StrategyType = value + }; + await PersistLogPersistenceStrategies(); + } + + private async Task OnInternalStateExpressionChanged(Expression? expression) + { + _persistenceConfiguration.InternalState = new() + { + EvaluationMode = LogPersistenceEvaluationMode.Expression, + Expression = expression + }; + await PersistLogPersistenceStrategies(); + } + + private async Task OnPropertyStrategyChanged(string propertyName, IDictionary properties, string? value) + { + SetLogPersistenceStrategyTypeName(propertyName, properties, value); + await PersistLogPersistenceStrategies(); + } + + private async Task OnPropertyExpressionChanged(string propertyName, IDictionary properties, Expression expression) + { + SetLogPersistenceExpression(propertyName, properties, expression); + await PersistLogPersistenceStrategies(); + } + + private async Task PersistLogPersistenceStrategies() + { + var props = _persistenceConfiguration.SerializeToNode(SerializerOptions.LogPersistenceConfigSerializerOptions); + Activity?.SetProperty(props, "customProperties", LogPersistenceConfigKey); + + await RaiseActivityUpdated(); + } + + private void SetPersistenceProperties() + { + var customProperties = GetCustomProperties(); + var legacyPersistence = ((JsonObject)customProperties).GetProperty(SerializerOptions.LogPersistenceConfigSerializerOptions, LogPersistenceModeKey) ?? new LegacyPersistenceActivityConfiguration(); + var persistence = ((JsonObject)customProperties).GetProperty(SerializerOptions.LogPersistenceConfigSerializerOptions, LogPersistenceConfigKey) ?? new PersistenceActivityConfiguration(); + + _legacyPersistenceConfiguration = legacyPersistence; + _persistenceConfiguration = persistence; + UpgradeLegacyModel(_persistenceConfiguration, _legacyPersistenceConfiguration); + + if (Activity == null) + return; + + var serializedLegacyPersistenceConfiguration = _legacyPersistenceConfiguration.SerializeToNode(SerializerOptions.LogPersistenceConfigSerializerOptions); + var serializedPersistenceConfiguration = _persistenceConfiguration.SerializeToNode(SerializerOptions.LogPersistenceConfigSerializerOptions); + Activity.SetProperty(serializedLegacyPersistenceConfiguration, "customProperties", LogPersistenceModeKey); + Activity.SetProperty(serializedPersistenceConfiguration, "customProperties", LogPersistenceConfigKey); + } + + private void UpgradeLegacyModel(PersistenceActivityConfiguration newModel, LegacyPersistenceActivityConfiguration oldModel) + { + // Update the new model with the legacy model. + foreach (var input in oldModel.Inputs) + { + if (newModel.Inputs.ContainsKey(input.Key)) + continue; + newModel.Inputs[input.Key] = new() + { + EvaluationMode = LogPersistenceEvaluationMode.Strategy, + StrategyType = input.Value.ToString() + }; + } + + foreach (var output in oldModel.Outputs) + { + if (newModel.Outputs.ContainsKey(output.Key)) + continue; + newModel.Outputs[output.Key] = new() + { + EvaluationMode = LogPersistenceEvaluationMode.Strategy, + StrategyType = output.Value.ToString() + }; + } + } + + private JsonNode GetCustomProperties() + { + var customProperties = Activity?.GetProperty("customProperties"); + if (customProperties != null) return customProperties; + customProperties = new JsonObject(new List>()); + Activity?.SetProperty(customProperties, "customProperties"); + return customProperties; + } + + private string? GetPropertyLogPersistenceStrategyTypeName(string propertyName, IDictionary properties) + { + return GetLogPersistenceConfig(propertyName, properties)?.StrategyType; + } + + private Expression? GetPropertyLogPersistenceExpression(string propertyName, IDictionary properties) + { + return GetLogPersistenceConfig(propertyName, properties)?.Expression; + } + + private LogPersistenceConfiguration? GetLogPersistenceConfig(string propertyName, IDictionary properties) + { + var prop = propertyName.Camelize(); + return properties.TryGetValue(prop, out var v) ? v : null; + } + + private void SetLogPersistenceStrategyTypeName(string propertyName, IDictionary properties, string? value) + { + var currentConfig = GetLogPersistenceConfig(propertyName, properties); + var prop = propertyName.Camelize(); + var config = new LogPersistenceConfiguration + { + EvaluationMode = LogPersistenceEvaluationMode.Strategy, + StrategyType = value, + Expression = currentConfig?.Expression + }; + properties[prop] = config; + } + + private void SetLogPersistenceExpression(string propertyName, IDictionary properties, Expression expression) + { + var currentConfig = GetLogPersistenceConfig(propertyName, properties); + var prop = propertyName.Camelize(); + var config = new LogPersistenceConfiguration + { + EvaluationMode = LogPersistenceEvaluationMode.Expression, + Expression = expression, + StrategyType = currentConfig?.StrategyType + }; + properties[prop] = config; + } + + [Obsolete] + private LogPersistenceMode GetPropertyLogPersistenceMode(string propertyName, IDictionary properties) + { + var prop = propertyName.Camelize(); + if (properties.All(o => o.Key != prop)) + properties[prop] = LogPersistenceMode.Inherit; + return properties[prop]; + } + + [Obsolete] + private void SetLogPersistenceMode(string propertyName, IDictionary properties, LogPersistenceMode value) + { + var prop = propertyName.Camelize(); + properties[prop] = value; + } + + private async Task RaiseActivityUpdated() + { + if (OnActivityUpdated != null) + await OnActivityUpdated(Activity!); + } + + private IDictionary GetExpressionEditorProps(PropertyDescriptor? propertyDescriptor) + { + var props = new Dictionary(); + + if(ActivityDescriptor != null) props[nameof(ActivityDescriptor)] = ActivityDescriptor; + if(propertyDescriptor != null) props[nameof(PropertyDescriptor)] = propertyDescriptor; + props["WorkflowDefinitionId"] = WorkflowDefinition!.DefinitionId; + + return props; + } +} + +/// +/// Defines the Persistence Strategy Configuration for an activity +/// +[Obsolete] +public class LegacyPersistenceActivityConfiguration +{ + /// + /// Default Configuration Strategy for the activity + /// + public LogPersistenceMode Default { get; set; } = LogPersistenceMode.Inherit; + + /// + /// Define Configuration Strategy for each Input properties + /// + public IDictionary Inputs { get; set; } = new Dictionary(); + + /// + /// Define Configuration Strategy for each Output properties + /// + public IDictionary Outputs { get; set; } = new Dictionary(); +} + +/// +/// Defines the Persistence Strategy Configuration for an activity +/// +public class PersistenceActivityConfiguration +{ + /// + /// Default strategy type name for the entire activity. + /// + public LogPersistenceConfiguration? Default { get; set; } + + /// + /// Strategy type name for internal activity state. + /// + public LogPersistenceConfiguration? InternalState { get; set; } + + /// + /// Strategy type names for individual Input properties. + /// + public IDictionary Inputs { get; set; } = new Dictionary(); + + /// + /// Strategy type names for individual Output properties. + /// + public IDictionary Outputs { get; set; } = new Dictionary(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Components/OutputsTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Components/OutputsTab.razor new file mode 100644 index 0000000..36aae2b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Components/OutputsTab.razor @@ -0,0 +1,51 @@ +@using Elsa.Studio.Workflows.Services +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Extensions +@using Elsa.Api.Client.Shared.Models +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs.Outputs.Models +@inherits StudioComponentBase +@using Microsoft.Extensions.Localization +@inject ILocalizer Localizer + +
+ + + @foreach (var outputDescriptor in OutputDescriptors) + { + var activity = Activity; + var displayName = string.IsNullOrWhiteSpace(outputDescriptor.DisplayName) ? outputDescriptor.Name : outputDescriptor.DisplayName; + var propertyName = outputDescriptor.Name.Camelize(); + var propertyValue = activity.GetProperty(propertyName); + var propertyType = _variableTypes.TryGetValue(outputDescriptor.TypeName, out var type) ? type : default; + var propertyTypeName = propertyType?.DisplayName ?? outputDescriptor.TypeName; + var selectedValue = _bindingTargetOptions.FirstOrDefault(x => x.Value == propertyValue?.MemoryReference?.Id); + + + - + @foreach (var bindingTargetGroup in _bindingTargetGroups) + { + @* MudSelect doesn't support (yet?), while MudSelectExtended does. However, MudSelectExtended doesn't seem to support AdornmentText (even though the property is exposed, it doesn't display) + * So we're not currently using MudSelectExtended and not rendering * + *@ + @foreach (var bindingTargetOption in bindingTargetGroup.Options) + { + @bindingTargetOption.Text + } + } + + } + + +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Components/OutputsTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Components/OutputsTab.razor.cs new file mode 100644 index 0000000..228f3e4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Components/OutputsTab.razor.cs @@ -0,0 +1,109 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.VariableTypes.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs.Outputs.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.UI.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs.Outputs.Components; + +/// +/// Displays the outputs of an activity. +/// +public partial class OutputsTab +{ + private ICollection _bindingTargetGroups = new List(); + private ICollection _bindingTargetOptions = new List(); + private IDictionary _variableTypes = new Dictionary(); + + /// + /// The workflow definition. + /// + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + + /// + /// The activity. + /// + [Parameter] public JsonObject Activity { get; set; } = default!; + + /// + /// The activity descriptor. + /// + [Parameter] public ActivityDescriptor ActivityDescriptor { get; set; } = default!; + + /// + /// An event raised when the activity is updated. + /// + [Parameter] public Func? OnActivityUpdated { get; set; } + + /// + /// The workspace. + /// + [CascadingParameter] public IWorkspace? Workspace { get; set; } + + [Inject] IVariableTypeService VariableTypeService { get; set; } = default!; + + private IReadOnlyCollection OutputDescriptors => ActivityDescriptor.Outputs; + private bool IsReadOnly => Workspace?.IsReadOnly == true; + + /// + protected override bool ShouldRender() => WorkflowDefinition != null! && Activity != null! && ActivityDescriptor != null!; + + /// + protected override async Task OnInitializedAsync() + { + _variableTypes = (await VariableTypeService.GetVariableTypesAsync()).ToDictionary(x => x.TypeName); + } + + /// + protected override Task OnParametersSetAsync() + { + var bindingTargetGroups = new List(); + var variables = WorkflowDefinition.Variables; + var outputDefinitions = WorkflowDefinition.Outputs; + + var variableBindingTargets = variables + .Select(variable => new BindingTargetOption(variable.Name, variable.Id)) + .ToList(); + + var outputBindingTargets = outputDefinitions + .Select(outputDefinition => new BindingTargetOption(outputDefinition.DisplayName, outputDefinition.Name)) + .ToList(); + + if (variableBindingTargets.Any()) bindingTargetGroups.Add(new BindingTargetGroup("Variables", BindingKind.Variable, variableBindingTargets)); + + if (outputBindingTargets.Any()) bindingTargetGroups.Add(new BindingTargetGroup("Outputs", BindingKind.Output, outputBindingTargets)); + + _bindingTargetGroups = bindingTargetGroups; + _bindingTargetOptions = variableBindingTargets.Concat(outputBindingTargets).ToList(); + return Task.CompletedTask; + } + + private async Task OnBindingChanged(BindingTargetOption? bindingTargetOption, OutputDescriptor outputDescriptor) + { + var activity = Activity; + var propertyName = outputDescriptor.Name.Camelize(); + + var activityOutput = bindingTargetOption == null + ? default + : new ActivityOutput + { + TypeName = outputDescriptor.TypeName, + MemoryReference = new MemoryReference + { + Id = bindingTargetOption.Value + } + }; + + activity.SetProperty(activityOutput!.SerializeToNode(), propertyName); + + if (OnActivityUpdated != null) + await OnActivityUpdated(activity); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingKind.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingKind.cs new file mode 100644 index 0000000..787bd32 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingKind.cs @@ -0,0 +1,7 @@ +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs.Outputs.Models; + +public enum BindingKind +{ + Variable, + Output +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingTargetGroup.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingTargetGroup.cs new file mode 100644 index 0000000..b52d129 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingTargetGroup.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs.Outputs.Models; + +public record BindingTargetGroup(string Text, BindingKind Kind, ICollection Options); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingTargetOption.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingTargetOption.cs new file mode 100644 index 0000000..d7b0657 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/Outputs/Models/BindingTargetOption.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs.Outputs.Models; + +public record BindingTargetOption(string Text, string Value); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/ResilienceTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/ResilienceTab.razor new file mode 100644 index 0000000..e4e4a2f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/ResilienceTab.razor @@ -0,0 +1,30 @@ +@using Elsa.Api.Client.Extensions +@using Variant = MudBlazor.Variant +@inject ILocalizer Localizer + + + + + @foreach (var strategy in ResilienceStrategies) + { + var id = strategy.GetResilienceStrategyId(); + var displayName = strategy.GetResilienceStrategyDisplayName(); + @Localizer[displayName] + } + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/ResilienceTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/ResilienceTab.razor.cs new file mode 100644 index 0000000..669fd1e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/ResilienceTab.razor.cs @@ -0,0 +1,130 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.Resilience.Models; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Components; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs; + +/// +/// The Task tab for an activity. +/// +public partial class ResilienceTab +{ + private const string DefaultCategory = "Default"; + private bool _isInitialized; + + /// + /// Gets or sets the workflow definition. + /// + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// The activity. + [Parameter] public JsonObject? Activity { get; set; } + + /// The activity descriptor. + [Parameter] public ActivityDescriptor? ActivityDescriptor { get; set; } = null!; + + /// An event raised when the activity is updated. + [Parameter] public Func? OnActivityUpdated { get; set; } + + [Inject] private IResilienceStrategyCatalog ResilienceStrategyCatalog { get; set; } = null!; + [CascadingParameter] private IWorkspace? Workspace { get; set; } + private ExpressionEditor? ExpressionEditor { get; set; } + private bool IsReadOnly => Workspace?.IsReadOnly == true; + private ICollection ResilienceStrategies { get; set; } = []; + private string ResilienceCategory { get; set; } = DefaultCategory; + private ResilienceStrategyConfig? ResilienceStrategyConfig { get; set; } + private Expression? Expression { get; set; } + private string? ResilienceStrategyId { get; set; } + + /// + protected override async Task OnParametersSetAsync() + { + if (Activity == null || ActivityDescriptor == null) + return; + + await SetPropertiesAsync(); + + if (!_isInitialized) + { + if (ResilienceStrategyConfig?.Mode == ResilienceStrategyConfigMode.Expression && Expression != null && ExpressionEditor != null) + { + _isInitialized = true; + await ExpressionEditor.UpdateAsync(Expression); + } + } + } + + /// + protected override async Task OnInitializedAsync() + { + var strategies = await ResilienceStrategyCatalog.ListAsync(ResilienceCategory); + ResilienceStrategies = strategies.ToList(); + } + + private IDictionary GetExpressionEditorProps() + { + var props = new Dictionary(); + + if (ActivityDescriptor != null) props[nameof(ActivityDescriptor)] = ActivityDescriptor; + props["WorkflowDefinitionId"] = WorkflowDefinition!.DefinitionId; + + return props; + } + + private async Task RaiseActivityUpdatedAsync() + { + if (OnActivityUpdated != null) + await OnActivityUpdated(Activity!); + } + + private async Task PersistStrategyConfigAsync() + { + var config = ResilienceStrategyConfig ?? new ResilienceStrategyConfig(); + var expressionType = Expression?.Type ?? "Default"; + config.Expression = Expression; + config.StrategyId = ResilienceStrategyId; + config.Mode = expressionType == "Default" ? ResilienceStrategyConfigMode.Identifier : ResilienceStrategyConfigMode.Expression; + ResilienceStrategyConfig = config; + Activity?.SetResilienceStrategy(config); + + await RaiseActivityUpdatedAsync(); + } + + private async Task SetPropertiesAsync() + { + if (Activity == null || ActivityDescriptor == null) + return; + + var config = Activity.GetResilienceStrategy(); + var previousCategory = ResilienceCategory; + ResilienceCategory = ActivityDescriptor.CustomProperties.TryGetValue("ResilienceCategory", out var category) ? category.ToString() ?? DefaultCategory : DefaultCategory; + ResilienceStrategyConfig = config; + Expression = config?.Expression; + ResilienceStrategyId = config?.StrategyId; + + if (previousCategory != ResilienceCategory || ResilienceStrategies.Count == 0) + { + var strategies = await ResilienceStrategyCatalog.ListAsync(ResilienceCategory); + ResilienceStrategies = strategies.ToList(); + } + } + + private async Task OnExpressionChangedAsync(Expression? expression) + { + Expression = expression; + await PersistStrategyConfigAsync(); + } + + private async Task OnStrategyChanged(string id) + { + ResilienceStrategyId = id; + await PersistStrategyConfigAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/TaskTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/TaskTab.razor new file mode 100644 index 0000000..6d8c868 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/TaskTab.razor @@ -0,0 +1,22 @@ +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Extensions +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/TaskTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/TaskTab.razor.cs new file mode 100644 index 0000000..d35f89e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/TaskTab.razor.cs @@ -0,0 +1,42 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs; + +/// +/// The Task tab for an activity. +/// +public partial class TaskTab +{ + /// The activity. + [Parameter] public JsonObject? Activity { get; set; } + + /// The activity descriptor. + [Parameter] + public ActivityDescriptor ActivityDescriptor { get; set; } = default!; + + /// An event raised when the activity is updated. + [Parameter] public Func? OnActivityUpdated { get; set; } + [CascadingParameter] private IWorkspace? Workspace { get; set; } + private bool IsReadOnly => Workspace?.IsReadOnly == true; + + /// + protected override void OnParametersSet() + { + } + + private async Task RaiseActivityUpdated() + { + if (OnActivityUpdated != null) + await OnActivityUpdated(Activity!); + } + + private async Task OnRunAsynchronouslyChanged(bool? value) + { + Activity!.SetRunAsynchronously(value == true); + await RaiseActivityUpdated(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/VersionTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/VersionTab.razor new file mode 100644 index 0000000..bf512b9 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/VersionTab.razor @@ -0,0 +1,43 @@ +@using Elsa.Api.Client.Resources.WorkflowDefinitions.Models +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +
+ + + @Localizer["Used"] + @Localizer["Version"] + @Localizer["Created"] + + + + + @if (context.Version == CurrentVersionUsed) + { + + } + + @context.Version + @context.CreatedAt.ToString("g") + + + @Localizer["Use this version"] + + + + + + + +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/VersionTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/VersionTab.razor.cs new file mode 100644 index 0000000..64eb259 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/VersionTab.razor.cs @@ -0,0 +1,90 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Enums; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties.Tabs; + +public partial class VersionTab +{ + [Parameter] public ActivityDescriptor ActivityDescriptor { get; set; } = default!; + [Parameter] public JsonObject Activity { get; set; } = default!; + [Parameter] public Func? OnActivityUpdated { get; set; } + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = default!; + [Inject] IActivityRegistry ActivityRegistry { get; set; } = default!; + private MudTable Table { get; set; } = default!; + [CascadingParameter] private IWorkspace? Workspace { get; set; } + private bool IsReadOnly => Workspace?.IsReadOnly == true; + + private string DefinitionId + { + get => Activity.GetProperty("workflowDefinitionId")!.GetValue(); + set => Activity.SetProperty(value, "workflowDefinitionId"); + } + + private string DefinitionVersionId + { + get => Activity.GetProperty("workflowDefinitionVersionId")!.GetValue(); + set => Activity.SetProperty(value, "workflowDefinitionVersionId"); + } + + private int CurrentVersionUsed + { + get => Activity.GetProperty("version")!.GetValue(); + set => Activity.SetProperty(value, "version"); + } + + private string CurrentActivityType => Activity.GetTypeName(); + + private IEnumerable _versionsUsableAsActivity = []; + + private async Task> LoadVersionsAsync(TableState tableState, CancellationToken cancellationToken) + { + if (Activity == null! || ActivityDescriptor == null!) + return new TableData(); + + var page = tableState.Page; + var pageSize = tableState.PageSize; + var definitionId = DefinitionId; + + var request = new ListWorkflowDefinitionsRequest + { + DefinitionIds = [definitionId], + OrderDirection = OrderDirection.Descending, + OrderBy = OrderByWorkflowDefinition.Version, + Page = page, + PageSize = pageSize + }; + + _versionsUsableAsActivity = ActivityRegistry.FindAll(CurrentActivityType).Select(d => d.Version); + + var response = await WorkflowDefinitionService.ListAsync(request, VersionOptions.All); + + return new TableData + { + Items = response.Items, + TotalItems = (int)response.TotalCount + }; + } + + private async Task OnUseVersionClicked(WorkflowDefinitionSummary workflowDefinitionVersion) + { + var version = workflowDefinitionVersion.Version; + + if (version == CurrentVersionUsed) + return; + + CurrentVersionUsed = version; + DefinitionVersionId = workflowDefinitionVersion.Id; + + if (OnActivityUpdated != null) + await OnActivityUpdated(Activity); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionVersionViewer.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionVersionViewer.razor new file mode 100644 index 0000000..d9af6db --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionVersionViewer.razor @@ -0,0 +1,23 @@ +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties +@using Orientation = Radzen.Orientation +@inherits WorkflowEditorComponentBase +@using Variant = MudBlazor.Variant +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + + + + + + + @Localizer["Export"] + + @($"Version {_workflowDefinition?.Version ?? 0}") + + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionVersionViewer.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionVersionViewer.razor.cs new file mode 100644 index 0000000..41d8345 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionVersionViewer.razor.cs @@ -0,0 +1,125 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.DomInterop.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Shared.Components; +using Elsa.Studio.Workflows.UI.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; +using Radzen; +using Radzen.Blazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components; + +public partial class WorkflowDefinitionVersionViewer +{ + private RadzenSplitterPane _activityPropertiesPane = default!; + private int _activityPropertiesPaneHeight = 300; + private DiagramDesignerWrapper? _diagramDesigner; + + /// Gets or sets the workflow definition to view. + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + + /// Gets or sets the event triggered when an activity is selected. + [Parameter] public Func? ActivitySelected { get; set; } + + /// Gets the ID of the selected activity. + public string? SelectedActivityId { get; private set; } + + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = default!; + [Inject] private IActivityVisitor ActivityVisitor { get; set; } = default!; + [Inject] private IDiagramDesignerService DiagramDesignerService { get; set; } = default!; + [Inject] private IDomAccessor DomAccessor { get; set; } = default!; + [Inject] private IFiles Files { get; set; } = default!; + + private JsonObject? Activity => _workflowDefinition?.Root; + private JsonObject? SelectedActivity { get; set; } + private ActivityDescriptor? ActivityDescriptor { get; set; } + private ActivityProperties.ActivityPropertiesPanel? ActivityPropertiesTab { get; set; } + + private RadzenSplitterPane ActivityPropertiesPane + { + get => _activityPropertiesPane; + set + { + _activityPropertiesPane = value; + + // Prefix the ID with a non-numerical value, so it can always be used as a query selector (sometimes, Radzen generates a unique ID starting with a number). + _activityPropertiesPane.UniqueID = $"pane-{value.UniqueID}"; + } + } + + /// + protected override async Task OnInitializedAsync() + { + _workflowDefinition = WorkflowDefinition; + await ActivityRegistry.EnsureLoadedAsync(); + + if (_workflowDefinition?.Root == null) + return; + + SelectActivity(_workflowDefinition.Root); + } + + /// + protected override async Task OnParametersSetAsync() + { + if (WorkflowDefinition == _workflowDefinition) + return; + + _workflowDefinition = WorkflowDefinition; + + if (_workflowDefinition?.Root == null) + return; + + if (_diagramDesigner != null) + await _diagramDesigner.LoadActivityAsync(_workflowDefinition.Root); + + SelectActivity(_workflowDefinition.Root); + } + + private void SelectActivity(JsonObject activity) + { + // Setting the activity to null first and then requesting an update is a workaround to ensure that BlazorMonaco gets destroyed first. + // Otherwise, the Monaco editor will not be updated with a new value. Perhaps we should consider updating the Monaco Editor via its imperative API instead of via binding. + SelectedActivity = null; + ActivityDescriptor = null; + StateHasChanged(); + + SelectedActivity = activity; + SelectedActivityId = activity.GetId(); + ActivityDescriptor = ActivityRegistry.Find(activity.GetTypeName(), activity.GetVersion()); + StateHasChanged(); + } + + private async Task OnActivitySelected(JsonObject activity) + { + SelectActivity(activity); + if(ActivitySelected != null) + await ActivitySelected(activity); + } + + private async Task OnSelectedActivityUpdated(JsonObject activity) + { + StateHasChanged(); + await _diagramDesigner!.UpdateActivityAsync(SelectedActivityId!, activity); + } + + private async Task OnDownloadClicked() + { + var download = await WorkflowDefinitionService.ExportDefinitionAsync(_workflowDefinition!.DefinitionId, VersionOptions.SpecificVersion(_workflowDefinition.Version)); + var fileName = $"{_workflowDefinition.Name.Kebaberize()}.json"; + await Files.DownloadFileFromStreamAsync(fileName, download.Content); + } + + private async Task OnResize(RadzenSplitterResizeEventArgs arg) + { + var paneQuerySelector = $"#{ActivityPropertiesPane.UniqueID}"; + var visibleHeight = await DomAccessor.GetVisibleHeightAsync(paneQuerySelector); + _activityPropertiesPaneHeight = (int)visibleHeight + 50; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionWorkspace.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionWorkspace.razor new file mode 100644 index 0000000..dd7ee11 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionWorkspace.razor @@ -0,0 +1,55 @@ +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties +@using Orientation = Radzen.Orientation +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + + + + + + @if (_selectedWorkflowDefinition != null) + { + + + + @if (!IsReadOnly) + { + + } + else + { + + } + + + + + } + + + + @if (_selectedWorkflowDefinition != null) + { + + } + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionWorkspace.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionWorkspace.razor.cs new file mode 100644 index 0000000..d2d65fa --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowDefinitionWorkspace.razor.cs @@ -0,0 +1,124 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Extensions; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components; + +/// A workspace for editing a workflow definition. +public partial class WorkflowDefinitionWorkspace : IWorkspace +{ + private MudDynamicTabs _dynamicTabs = null!; + private WorkflowDefinition? _workflowDefinition = null!; + private WorkflowDefinition? _selectedWorkflowDefinition = null!; + + /// Gets or sets the workflow definition to edit. + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = null!; + + /// Gets or sets a specific version of the workflow definition to view. + [Parameter] public WorkflowDefinition SelectedWorkflowDefinition { get; set; } = null!; + + /// An event that is invoked when a workflow definition has been executed. + /// The ID of the workflow instance is provided as the value to the event callback. + [Parameter] public Func? WorkflowDefinitionExecuted { get; set; } + + /// Gets or sets the event that occurs when the workflow definition version is updated. + [Parameter] public Func? WorkflowDefinitionVersionSelected { get; set; } + + /// Gets or sets the event that occurs when an activity is selected. + [Parameter] public Func? ActivitySelected { get; set; } + + /// An event that is invoked when the workflow definition is updated. + public event Func? WorkflowDefinitionUpdated; + + /// + public bool IsReadOnly => _selectedWorkflowDefinition.GetIsReadOnly(); + + /// + public bool HasWorkflowEditPermission => (_selectedWorkflowDefinition?.Links?.Count(l => l.Rel == "publish") ?? 0) > 0; + + /// Gets the selected activity ID. + public string? SelectedActivityId => WorkflowEditor.SelectedActivityId; + + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = null!; + [Inject] private IMediator Mediator { get; set; } = null!; + + private WorkflowEditor WorkflowEditor { get; set; } = null!; + + /// + protected override void OnInitialized() + { + _workflowDefinition = WorkflowDefinition; + _selectedWorkflowDefinition = SelectedWorkflowDefinition; + } + + /// + protected override void OnParametersSet() + { + _workflowDefinition = WorkflowDefinition; + _selectedWorkflowDefinition = SelectedWorkflowDefinition; + + if (_selectedWorkflowDefinition == null) + _selectedWorkflowDefinition = _workflowDefinition; + } + + /// Displays the specified workflow definition version. + public async Task DisplayWorkflowDefinitionVersionAsync(WorkflowDefinition workflowDefinition) + { + if(_selectedWorkflowDefinition == workflowDefinition) + return; + + _selectedWorkflowDefinition = workflowDefinition; + + if(workflowDefinition.IsLatest) + _workflowDefinition = workflowDefinition; + + if (WorkflowDefinitionVersionSelected != null) + await WorkflowDefinitionVersionSelected(_selectedWorkflowDefinition); + + StateHasChanged(); + } + + /// Gets the currently selected workflow definition version. + public WorkflowDefinition? GetSelectedWorkflowDefinitionVersion() => _selectedWorkflowDefinition; + + /// Determines whether the workspace is currently viewing a specific version of a workflow definition. + public bool IsSelectedDefinition(string definitionVersionId) + { + return _selectedWorkflowDefinition?.Id == definitionVersionId; + } + + /// Gets the selected workflow definition. + public WorkflowDefinition? GetSelectedDefinition() + { + return _selectedWorkflowDefinition; + } + + /// Displays the latest version of a workflow definition asynchronously. + public async Task DisplayLatestWorkflowDefinitionVersionAsync() + { + var definitionId = _workflowDefinition!.DefinitionId; + var definition = (await WorkflowDefinitionService.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest))!; + await DisplayWorkflowDefinitionVersionAsync(definition); + } + + private async Task OnWorkflowDefinitionPropsUpdated() + { + await WorkflowEditor.NotifyWorkflowChangedAsync(); + } + + private async Task OnWorkflowDefinitionUpdated() + { + _workflowDefinition = WorkflowEditor.WorkflowDefinition!; + _selectedWorkflowDefinition = _workflowDefinition; + StateHasChanged(); + + if (WorkflowDefinitionUpdated != null) + await WorkflowDefinitionUpdated(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditor.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditor.razor new file mode 100644 index 0000000..f2e91c3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditor.razor @@ -0,0 +1,57 @@ +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties +@using Elsa.Studio.Workflows.Services +@using Orientation = Radzen.Orientation +@using Variant = MudBlazor.Variant +@inherits WorkflowEditorComponentBase +@inject ILocalizer Localizer + + + + + + + + + + + + +
+ +
+ + + + + + @if (_workflowDefinition?.IsPublished == true) + { + + @Localizer["Unpublish"] + + + } + + @Localizer["Export"] + + + @Localizer["Import"] + + + + + +
+
+
+ + + +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditor.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditor.razor.cs new file mode 100644 index 0000000..7427a80 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditor.razor.cs @@ -0,0 +1,408 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Responses; +using Elsa.Studio.Contracts; +using Elsa.Studio.DomInterop.Contracts; +using Elsa.Studio.Extensions; +using Elsa.Studio.Localization; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.Shared.Components; +using Elsa.Studio.Workflows.UI.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using Microsoft.Extensions.Logging; +using MudBlazor; +using Radzen; +using Radzen.Blazor; +using ThrottleDebounce; +using Variant = MudBlazor.Variant; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components; + +/// A component that allows the user to edit a workflow definition. +public partial class WorkflowEditor +{ + private readonly RateLimitedFunc _rateLimitedSaveChangesAsync; + private bool _autoSave = true; + private bool _isDirty; + private RadzenSplitterPane _activityPropertiesPane = null!; + private int _activityPropertiesPaneHeight = 300; + private DiagramDesignerWrapper _diagramDesigner = null!; + + /// + public WorkflowEditor() + { + _rateLimitedSaveChangesAsync = Debouncer.Debounce(readDiagram => SaveChangesAsync(readDiagram, false, false), TimeSpan.FromMilliseconds(500)); + } + + /// Gets or sets the drag and drop manager via property injection. + [CascadingParameter] public DragDropManager DragDropManager { get; set; } = null!; + + /// Gets or sets the workflow definition. + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// Gets or sets a callback invoked when the workflow definition is updated. + [Parameter] public Func? WorkflowDefinitionUpdated { get; set; } + + /// Gets or sets the event triggered when an activity is selected. + [Parameter] public Func? ActivitySelected { get; set; } + + /// Gets the selected activity ID. + public string? SelectedActivityId { get; private set; } + + [Inject] private IWorkflowDefinitionEditorService WorkflowDefinitionEditorService { get; set; } = null!; + [Inject] private IWorkflowDefinitionImporter WorkflowDefinitionImporter { get; set; } = null!; + [Inject] private IActivityVisitor ActivityVisitor { get; set; } = null!; + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = null!; + [Inject] private IDiagramDesignerService DiagramDesignerService { get; set; } = null!; + [Inject] private IDomAccessor DomAccessor { get; set; } = null!; + [Inject] private IFiles Files { get; set; } = null!; + [Inject] private IMediator Mediator { get; set; } = null!; + [Inject] private IServiceProvider ServiceProvider { get; set; } = null!; + [Inject] private ILogger Logger { get; set; } = null!; + [Inject] private IWorkflowJsonDetector WorkflowJsonDetector { get; set; } = null!; + [Inject] private IBackendApiClientProvider BackendApiClientProvider { get; set; } = null!; + + private JsonObject? Activity => _workflowDefinition?.Root; + private JsonObject? SelectedActivity { get; set; } + private ActivityDescriptor? ActivityDescriptor { get; set; } + private ActivityPropertiesPanel? ActivityPropertiesPanel { get; set; } + + private RadzenSplitterPane ActivityPropertiesPane + { + get => _activityPropertiesPane; + set + { + _activityPropertiesPane = value; + + // Prefix the ID with a non-numerical value, so it can always be used as a query selector + // (sometimes, Radzen generates a unique ID starting with a number). + _activityPropertiesPane.UniqueID = $"pane-{value.UniqueID}"; + } + } + + /// Gets or sets a flag indicating whether the workflow definition is dirty. + public async Task NotifyWorkflowChangedAsync() + { + await HandleChangesAsync(false); + } + + /// + protected override async Task OnInitializedAsync() + { + _workflowDefinition = WorkflowDefinition; + + await ActivityRegistry.EnsureLoadedAsync(); + + if (_workflowDefinition?.Root == null) + return; + + SelectActivity(_workflowDefinition.Root); + } + + /// + protected override async Task OnParametersSetAsync() + { + if (WorkflowDefinition == _workflowDefinition) + return; + + _workflowDefinition = WorkflowDefinition; + + if (_workflowDefinition?.Root == null) + return; + + await _diagramDesigner.LoadActivityAsync(_workflowDefinition!.Root); + SelectActivity(_workflowDefinition.Root); + } + + /// + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + await UpdateActivityPropertiesVisibleHeightAsync(); + } + + private async Task HandleChangesAsync(bool readDiagram) + { + _isDirty = true; + StateHasChanged(); + + if (_autoSave) + await SaveChangesRateLimitedAsync(readDiagram); + } + + private async Task> SaveAsync(bool readDiagram, bool publish) + { + var workflowDefinition = _workflowDefinition ?? new WorkflowDefinition(); + + if (readDiagram) + { + var root = await _diagramDesigner.GetActivityAsync(); + workflowDefinition.Root = root; + } + + var result = await WorkflowDefinitionEditorService.SaveAsync(workflowDefinition, publish, async definition => await SetWorkflowDefinitionAsync(definition)); + + _isDirty = false; + StateHasChanged(); + + return result; + } + + private async Task PublishAsync(Func? onSuccess = null, Func? onFailure = null) + { + await SaveChangesAsync(true, true, true, onSuccess, onFailure); + } + + private async Task RetractAsync(Func? onSuccess = null, Func? onFailure = null) + { + var result = await WorkflowDefinitionEditorService.RetractAsync(_workflowDefinition!, async definition => await SetWorkflowDefinitionAsync(definition)); + await result.OnSuccessAsync(async _ => + { + if (onSuccess != null) await onSuccess(); + }); + + await result.OnFailedAsync(async errors => + { + if (onFailure != null) await onFailure(errors); + }); + } + + private async Task SaveChangesRateLimitedAsync(bool readDiagram) + { + await _rateLimitedSaveChangesAsync.InvokeAsync(readDiagram); + } + + private async Task SaveChangesAsync(bool readDiagram, bool showLoader, bool publish, Func? onSuccess = null, Func? onFailure = null) + { + await InvokeAsync(async () => + { + if (showLoader) + { + IsProgressing = true; + StateHasChanged(); + } + + // Because this method is rate-limited, it's possible that the designer has been disposed of since the last invocation. + // Therefore, we need to wrap this in a try/catch block. + try + { + var result = await SaveAsync(readDiagram, publish); + await result.OnSuccessAsync(response => + { + onSuccess?.Invoke(response); + return Task.CompletedTask; + }).ConfigureAwait(false); + + await result.OnFailedAsync(errors => + { + onFailure?.Invoke(errors); + foreach (var error in errors.Errors) + Snackbar.Add(error.ErrorMessage, Severity.Error, options => options.VisibleStateDuration = 5000); + return Task.CompletedTask; + }); + } + finally + { + if (showLoader) + { + IsProgressing = false; + StateHasChanged(); + } + } + }); + } + + private void SelectActivity(JsonObject activity) + { + // Setting the activity to null first and then requesting an update is a workaround to ensure that BlazorMonaco gets destroyed first. + // Otherwise, the Monaco editor will not be updated with a new value. Perhaps we should consider updating the Monaco Editor via its imperative API instead of via binding. + SelectedActivity = null; + ActivityDescriptor = null; + StateHasChanged(); + + SelectedActivity = activity; + SelectedActivityId = activity.GetId(); + ActivityDescriptor = ActivityRegistry.Find(activity.GetTypeName(), activity.GetVersion()); + StateHasChanged(); + } + + private async Task SetWorkflowDefinitionAsync(WorkflowDefinition workflowDefinition) + { + _workflowDefinition = WorkflowDefinition = workflowDefinition; + if (WorkflowDefinitionUpdated != null) await WorkflowDefinitionUpdated(); + } + + private async Task GetApiAsync(CancellationToken cancellationToken = default) + { + return await BackendApiClientProvider.GetApiAsync(cancellationToken); + } + + private async Task UpdateActivityPropertiesVisibleHeightAsync() + { + var paneQuerySelector = $"#{ActivityPropertiesPane.UniqueID}"; + var visibleHeight = await DomAccessor.GetVisibleHeightAsync(paneQuerySelector); + _activityPropertiesPaneHeight = (int)visibleHeight - 50; + } + + private async Task OnActivitySelected(JsonObject activity) + { + SelectActivity(activity); + if (ActivitySelected != null) await ActivitySelected(activity); + } + + private async Task OnSelectedActivityUpdated(JsonObject activity) + { + _isDirty = true; + StateHasChanged(); + await _diagramDesigner.UpdateActivityAsync(SelectedActivityId!, activity); + } + + private async Task OnSaveClick() + { + await SaveChangesAsync(true, true, false, _ => + { + Snackbar.Add(Localizer["Workflow saved"], Severity.Success); + return Task.CompletedTask; + }); + } + + private async Task OnPublishClicked() + { + await ProgressAsync(async () => await PublishAsync(async response => + { + // Depending on whether the workflow contains Not Found activities, display a different message. + var graph = await _diagramDesigner.GetActivityGraphAsync(); + var nodes = graph.ActivityNodeLookup.Values; + var hasNotFoundActivities = nodes.Any(x => x.Activity.GetTypeName() == "Elsa.NotFoundActivity"); + + if (hasNotFoundActivities) + Snackbar.Add(Localizer["Workflow published with Not Found activities"], Severity.Warning, options => options.VisibleStateDuration = 5000); + else + Snackbar.Add(Localizer["Workflow published"], Severity.Success); + + if (response.ConsumingWorkflowCount > 0) + { + Snackbar.Add(Localizer["{0} consuming workflow(s) updated", response.ConsumingWorkflowCount], Severity.Success, options => options.VisibleStateDuration = 3000); + } + })); + } + + private async Task OnRetractClicked() + { + await ProgressAsync(async () => await RetractAsync(() => + { + Snackbar.Add(Localizer["Workflow unpublished"], Severity.Success); + return Task.CompletedTask; + }, errors => + { + Snackbar.Add(string.Join(Environment.NewLine, errors), Severity.Error); + return Task.CompletedTask; + })); + } + + private async Task OnGraphUpdated() => await HandleChangesAsync(true); + + private async Task OnActivityUpdated(JsonObject activity) + { + await HandleChangesAsync(true); + } + + private async Task OnResize(RadzenSplitterResizeEventArgs arg) + { + await UpdateActivityPropertiesVisibleHeightAsync(); + } + + private async Task OnAutoSaveChanged(bool? value) + { + _autoSave = value ?? false; + + if (_autoSave) + await SaveChangesAsync(true, false, false); + } + + private async Task OnExportClicked() + { + var download = await WorkflowDefinitionEditorService.ExportAsync(_workflowDefinition!); + var fileName = $"{_workflowDefinition!.Name.Kebaberize()}.json"; + if (download.Content.CanSeek) download.Content.Seek(0, SeekOrigin.Begin); + await Files.DownloadFileFromStreamAsync(fileName, download.Content); + } + + private async Task OnImportClicked() + { + await DomAccessor.ClickElementAsync("#workflow-file-upload-button-wrapper input[type=file]"); + } + + private async Task OnFilesSelected(IReadOnlyList? files) + { + if (files == null || files.Count == 0) + return; + + await ImportFilesAsync(files); + _isDirty = false; + + StateHasChanged(); + } + + private async Task ImportFilesAsync(IReadOnlyList files) + { + _isDirty = true; + IsProgressing = true; + StateHasChanged(); + + var options = new ImportOptions + { + DefinitionId = WorkflowDefinition?.DefinitionId, + ImportedCallback = async definition => + { + await SetWorkflowDefinitionAsync(definition); + await _diagramDesigner.LoadActivityAsync(definition.Root); + }, + ErrorCallback = ex => + { + Snackbar.Add($"Failed to import workflow definition: {ex.Message}", Severity.Error); + return Task.CompletedTask; + } + }; + var importResults = (await WorkflowDefinitionImporter.ImportFilesAsync(files, options)).ToList(); + var failedImports = importResults.Where(x => !x.IsSuccess).ToList(); + var successfulImports = importResults.Where(x => x.IsSuccess).ToList(); + + IsProgressing = false; + _isDirty = false; + StateHasChanged(); + + if (importResults.Count == 0) + { + Snackbar.Add(Localizer["No workflows were imported."], Severity.Info); + return; + } + + if (successfulImports.Count == 1) + Snackbar.Add(Localizer["Successfully imported 1 workflow definition."], Severity.Success, ConfigureSnackbar); + else if (importResults.Count > 1) + Snackbar.Add(Localizer["Successfully imported {0} workflow definitions.", importResults.Count], Severity.Success, ConfigureSnackbar); + + if (failedImports.Count == 1) + Snackbar.Add(Localizer["Failed to import 1 workflow definition: {0}", failedImports[0].Failure!.ErrorMessage], Severity.Error, ConfigureSnackbar); + else if (failedImports.Count > 1) + Snackbar.Add(Localizer["Failed to import {0} workflow definitions. Errors: {1}", failedImports.Count, string.Join(", ", failedImports.Select(x => x.Failure!.ErrorMessage))], Severity.Error, ConfigureSnackbar); + + return; + void ConfigureSnackbar(SnackbarOptions snackbarOptions) + { + snackbarOptions.SnackbarVariant = Variant.Filled; + snackbarOptions.CloseAfterNavigation = failedImports.Count > 0; + snackbarOptions.VisibleStateDuration = failedImports.Count > 0 ? 10000 : 3000; + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditorComponentBase.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditorComponentBase.cs new file mode 100644 index 0000000..4b4afe3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowEditorComponentBase.cs @@ -0,0 +1,91 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Components; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Contracts; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components; + +public abstract class WorkflowEditorComponentBase : StudioComponentBase +{ + protected WorkflowDefinition? _workflowDefinition; + protected bool IsProgressing { get; set; } + + /// An event that is invoked when a workflow definition has been executed. + /// The ID of the workflow instance is provided as the value to the event callback. + [Parameter] public Func? WorkflowDefinitionExecuted { get; set; } + + /// + /// The injected workflow definition service. + /// + [Inject] protected IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = default!; + [Inject] private ILocalizer Localizer { get; set; } = default!; + + /// + /// The injected snackbar service. + /// + [Inject] protected ISnackbar Snackbar { get; set; } = default!; + + /// + /// The injected navigation manager. + /// + [Inject] protected NavigationManager NavigationManager { get; set; } = default!; + + /// + /// Invoked when the user clicked the "Run Workflow" button. + /// + protected async Task OnRunWorkflowClicked() + { + var executeResult = await ProgressAsync(async () => + { + var request = new ExecuteWorkflowDefinitionRequest + { + VersionOptions = VersionOptions.Latest + }; + + var definitionId = _workflowDefinition!.DefinitionId; + return await WorkflowDefinitionService.ExecuteAsync(definitionId, request); + }); + + if (executeResult.CannotStart) + { + Snackbar.Add(Localizer["The workflow cannot be started"], Severity.Error); + return; + } + + var workflowInstanceId = executeResult.WorkflowInstanceId; + + if(workflowInstanceId != null) + { + Snackbar.Add(Localizer["Successfully started workflow"], Severity.Success); + + if (WorkflowDefinitionExecuted != null) + await WorkflowDefinitionExecuted(workflowInstanceId); + else + NavigationManager.NavigateTo($"workflows/instances/{workflowInstanceId}/view"); + } + } + + protected async Task ProgressAsync(Func action) + { + IsProgressing = true; + StateHasChanged(); + await action.Invoke(); + IsProgressing = false; + StateHasChanged(); + } + + protected async Task ProgressAsync(Func> action) + { + IsProgressing = true; + StateHasChanged(); + var result = await action.Invoke(); + IsProgressing = false; + StateHasChanged(); + + return result; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/InputOutputTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/InputOutputTab.razor new file mode 100644 index 0000000..84da7a1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/InputOutputTab.razor @@ -0,0 +1,11 @@ +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Inputs +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Outputs +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Outcomes +@using Variant = MudBlazor.Variant + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/InputOutputTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/InputOutputTab.razor.cs new file mode 100644 index 0000000..7dcadaa --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/InputOutputTab.razor.cs @@ -0,0 +1,15 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components; + +public partial class InputOutputTab +{ + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } + [CascadingParameter] public IWorkspace? Workspace { get; set; } + + private bool IsReadOnly => Workspace?.IsReadOnly ?? true; + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/EditInputDialog.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/EditInputDialog.razor new file mode 100644 index 0000000..3634885 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/EditInputDialog.razor @@ -0,0 +1,51 @@ +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Resources.StorageDrivers.Models +@using Elsa.Api.Client.Resources.VariableTypes.Models +@using Elsa.Api.Client.Resources.WorkflowDefinitions.Models +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@inherits StudioComponentBase + + + + + + + + + @foreach (var grouping in _groupedVariableTypes) + { + + @foreach (var variableType in grouping) + { + @variableType.DisplayName + } + + } + + + + + + + + + @foreach(var uiHint in _uiHints) + { + @uiHint.DisplayName + } + + + @foreach (var storageDriver in _storageDriverDescriptors) + { + @storageDriver.DisplayName + } + + + + + + @Localizer["Cancel"] + @Localizer["Ok"] + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/EditInputDialog.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/EditInputDialog.razor.cs new file mode 100644 index 0000000..e451fff --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/EditInputDialog.razor.cs @@ -0,0 +1,136 @@ +using Blazored.FluentValidation; +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.VariableTypes.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Models; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Validators; +using Elsa.Studio.Workflows.Domain.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Inputs; + +public partial class EditInputDialog +{ + private readonly InputDefinitionModel _model = new(); + private EditContext _editContext = default!; + private InputModelValidator _validator = default!; + private FluentValidationValidator _fluentValidationValidator = default!; + private ICollection _storageDriverDescriptors = new List(); + private ICollection _variableTypes = new List(); + private ICollection _uiHints = new List(); + private ICollection> _groupedVariableTypes = new List>(); + + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + [Parameter] public InputDefinition? Input { get; set; } + [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; + [Inject] private IStorageDriverService StorageDriverService { get; set; } = default!; + [Inject] private IVariableTypeService VariableTypeService { get; set; } = default!; + + /// + protected override async Task OnInitializedAsync() + { + _editContext = new(_model); + _storageDriverDescriptors = (await StorageDriverService.GetStorageDriversAsync()).ToList(); + _variableTypes = (await VariableTypeService.GetVariableTypesAsync()).ToList(); + _uiHints = (await GetUIHintsAsync()).ToList(); + _groupedVariableTypes = _variableTypes.GroupBy(x => x.Category).ToList(); + } + + /// + protected override void OnParametersSet() + { + _editContext = new(_model); + _validator = new(WorkflowDefinition, Localizer); + + if (Input == null) + { + _model.Name = GetNewInputName(WorkflowDefinition.Inputs); + _model.DisplayName = _model.Name.Humanize(); + _model.StorageDriver = _storageDriverDescriptors.First(); + _model.Type = _variableTypes.First(); + _model.UIHint = _uiHints.First(); + } + else + { + _model.Name = Input.Name; + _model.Type = _variableTypes.FirstOrDefault(x => x.TypeName == Input.Type) ?? _variableTypes.First(); + _model.IsArray = Input.IsArray; + _model.StorageDriver = _storageDriverDescriptors.FirstOrDefault(x => x.TypeName == Input.StorageDriverType) ?? _storageDriverDescriptors.First(); + _model.UIHint = _uiHints.FirstOrDefault(x => x.Name == Input.UIHint) ?? _uiHints.First(); + _model.Description = Input.Description; + _model.Category = Input.Category; + _model.DisplayName = Input.DisplayName; + } + } + + private string GetNewInputName(ICollection existingInputs) + { + var count = 0; + + while (true) + { + var inputName = $"Input{++count}"; + + if (existingInputs.All(x => x.Name != inputName)) + return inputName; + } + } + + private Task> GetUIHintsAsync() + { + // TODO: Get these from the backend. + var descriptors = new[] + { + new UIHintDescriptor("singleline", Localizer["Single line"], Localizer["A single line of text input"]), + new UIHintDescriptor("multiline", Localizer["Multi line"], Localizer["Multiple lines of text input"]), + new UIHintDescriptor("checkbox", Localizer["Checkbox"], Localizer["A checkbox"]), + new UIHintDescriptor("checklist", Localizer["Checklist"], Localizer["A list of checkboxes"]), + new UIHintDescriptor("radiolist", Localizer["Radio list"], Localizer["A list of radio buttons"]), + new UIHintDescriptor("dropdown", Localizer["Dropdown"], Localizer["A dropdown list"]), + new UIHintDescriptor("multitext", Localizer["Multi text"], Localizer["An input for multiple words, like a tagging input"]), + new UIHintDescriptor("code-editor", Localizer["Code editor"], Localizer["A code editor"]), + new UIHintDescriptor("variable-picker", Localizer["Variable picker"], Localizer["A variable picker"]), + new UIHintDescriptor("workflow-definition-picker", Localizer["Workflow definition picker"], Localizer["A workflow definition picker"]), + new UIHintDescriptor("output-picker", Localizer["Output picker"], Localizer["A workflow output definition picker"]), + new UIHintDescriptor("outcome-picker", Localizer["Outcome picker"], Localizer["An outcome picker"]), + new UIHintDescriptor("json-editor", Localizer["JSON editor"], Localizer["A JSON editor"]), + }; + + return Task.FromResult(descriptors.AsEnumerable()); + } + + private Task OnCancelClicked() + { + MudDialog.Cancel(); + return Task.CompletedTask; + } + + private async Task OnSubmitClicked() + { + if (!await _fluentValidationValidator.ValidateAsync()) + return; + + await OnValidSubmit(); + } + + private Task OnValidSubmit() + { + var input = Input ?? new InputDefinition(); + + input.Name = _model.Name; + input.Type = _model.Type.TypeName; + input.IsArray = _model.IsArray; + input.StorageDriverType = _model.StorageDriver.TypeName; + input.Category = _model.Type.Category; + input.UIHint = _model.UIHint!.Name; + input.Description = _model.Description; + input.DisplayName = _model.DisplayName; + + MudDialog.Close(input); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/InputsSection.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/InputsSection.razor new file mode 100644 index 0000000..bc3582b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/InputsSection.razor @@ -0,0 +1,58 @@ +@using Variant = MudBlazor.Variant +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +@Localizer["Inputs"] + + + + @Localizer["Add input"] + + + @if (!Inputs.Any()) + { + @Localizer["There are currently no inputs defined."] + } + else + { + + + + @Localizer["Name"] + @Localizer["Type"] + @Localizer["Storage"] + + + + + + @foreach (var input in Inputs) + { + var storageDescriptor = input.StorageDriverType != null ? GetStorageDriverDescriptor(input.StorageDriverType) : default; + var storageDriverName = storageDescriptor != null ? storageDescriptor.DisplayName : @Localizer["None"]; + var typeDescriptor = input.Type != null ? _variableTypes.FirstOrDefault(x => x.TypeName == input.Type) : default; + var typeName = typeDescriptor?.DisplayName ?? input.Type; + if(input.IsArray) typeName += "[]"; + + @input.Name + @typeName + @storageDriverName + + + @Localizer["Edit"] + @Localizer["Delete"] + + + + } + + + } + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/InputsSection.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/InputsSection.razor.cs new file mode 100644 index 0000000..6744e50 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Inputs/InputsSection.razor.cs @@ -0,0 +1,99 @@ +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.VariableTypes.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Contracts; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Inputs; + +public partial class InputsSection +{ + private ICollection _variableTypes = new List(); + private ICollection _storageDriverDescriptors = new List(); + + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } + [Parameter] public bool IsReadonly { get; set; } = default; + [Inject] private IStorageDriverService StorageDriverService { get; set; } = default!; + [Inject] private IDialogService DialogService { get; set; } = default!; + [Inject] private IVariableTypeService VariableTypeService { get; set; } = default!; + + private ICollection Inputs => WorkflowDefinition.Inputs; + + protected override async Task OnInitializedAsync() + { + _storageDriverDescriptors = (await StorageDriverService.GetStorageDriversAsync()).ToList(); + _variableTypes = (await VariableTypeService.GetVariableTypesAsync()).ToList(); + } + + private StorageDriverDescriptor? GetStorageDriverDescriptor(string typeName) + { + return _storageDriverDescriptors.FirstOrDefault(x => x.TypeName == typeName); + } + + private async Task RaiseWorkflowDefinitionUpdatedAsync() + { + if (WorkflowDefinitionUpdated.HasDelegate) + await WorkflowDefinitionUpdated.InvokeAsync(); + } + + private async Task OpenInputEditorDialog(InputDefinition? inputDefinition) + { + var isNew = inputDefinition == null; + + var parameters = new DialogParameters + { + [nameof(EditInputDialog.WorkflowDefinition)] = WorkflowDefinition + }; + + if (!isNew) + parameters[nameof(EditInputDialog.Input)] = inputDefinition; + + var options = new DialogOptions + { + MaxWidth = MaxWidth.Medium, + FullWidth = true, + CloseButton = true, + CloseOnEscapeKey = true + }; + + var title = inputDefinition == null ? Localizer["Create input"] : Localizer["Edit input"]; + var dialog = await DialogService.ShowAsync(title, parameters, options); + var result = await dialog.Result; + + if (result.Canceled) + return; + + if (isNew) + { + inputDefinition = (InputDefinition)result.Data; + WorkflowDefinition.Inputs.Add(inputDefinition); + } + + await RaiseWorkflowDefinitionUpdatedAsync(); + } + + private async Task OnEditClicked(InputDefinition input) + { + await OpenInputEditorDialog(input); + } + + private async Task OnDeleteClicked(InputDefinition input) + { + var result = await DialogService.ShowMessageBox(Localizer["Delete selected input?"], Localizer["Are you sure you want to delete the selected input?"], yesText: Localizer["Delete"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + WorkflowDefinition.Inputs.Remove(input); + + await RaiseWorkflowDefinitionUpdatedAsync(); + } + + private async Task OnAddInputClicked() + { + await OpenInputEditorDialog(null); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outcomes/OutcomesSection.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outcomes/OutcomesSection.razor new file mode 100644 index 0000000..11feed1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outcomes/OutcomesSection.razor @@ -0,0 +1,29 @@ +@using Variant = MudBlazor.Variant +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@if (WorkflowDefinition != null!) +{ + @Localizer["Outcomes"] + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outcomes/OutcomesSection.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outcomes/OutcomesSection.razor.cs new file mode 100644 index 0000000..cd8597a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outcomes/OutcomesSection.razor.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using MudExtensions; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Outcomes; + +public partial class OutcomesSection +{ + private MudChipField _chipField = default!; + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } + [Parameter] public bool IsReadonly { get; set; } = default; + + private List Outcomes => WorkflowDefinition.Outcomes.ToList(); + + private async Task OnValuesChanges(List values) + { + WorkflowDefinition.Outcomes = values; + if (WorkflowDefinitionUpdated.HasDelegate) + await WorkflowDefinitionUpdated.InvokeAsync(); + } + + private void OnKeyDown(KeyboardEventArgs arg) + { + // TODO: This is a hack to get the chips to update when the user presses enter. + // Ideally, we can configure this on MudChipField, but this is not currently supported. + if (arg.Key is not ("Enter" or "Tab")) return; + + var setChipsMethod = _chipField.GetType().GetMethod("SetChips", BindingFlags.Instance | BindingFlags.NonPublic); + setChipsMethod!.Invoke(_chipField, null); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/EditOutputDialog.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/EditOutputDialog.razor new file mode 100644 index 0000000..76960d1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/EditOutputDialog.razor @@ -0,0 +1,37 @@ +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Resources.VariableTypes.Models +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + + + + + + + + + @foreach (var grouping in _groupedVariableTypes) + { + + @foreach (var variableType in grouping) + { + @variableType.DisplayName + } + + } + + + + + + + + + + + + @Localizer["Cancel"] + @Localizer["Ok"] + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/EditOutputDialog.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/EditOutputDialog.razor.cs new file mode 100644 index 0000000..2723b24 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/EditOutputDialog.razor.cs @@ -0,0 +1,110 @@ +using Blazored.FluentValidation; +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.VariableTypes.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Models; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Validators; +using Elsa.Studio.Workflows.Domain.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Outputs; + +/// +/// A dialog for editing an output. +/// +public partial class EditOutputDialog +{ + private readonly OutputDefinitionModel _model = new(); + private EditContext _editContext = null!; + private OutputModelValidator _validator = null!; + private FluentValidationValidator _fluentValidationValidator = null!; + private ICollection _storageDriverDescriptors = new List(); + private ICollection _variableTypes = new List(); + private ICollection> _groupedVariableTypes = new List>(); + + /// + /// The workflow definition. + /// + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = null!; + + /// + /// The output to edit. + /// + [Parameter] public OutputDefinition? Output { get; set; } + [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = null!; + [Inject] private IStorageDriverService StorageDriverService { get; set; } = null!; + [Inject] private IVariableTypeService VariableTypeService { get; set; } = null!; + + /// + protected override async Task OnParametersSetAsync() + { + // Instantiate the edit context first so that it is available when rendering (which happens as soon as we call an async method on the next line). + _editContext = new(_model); + _validator = new(WorkflowDefinition, Localizer); + + _storageDriverDescriptors = (await StorageDriverService.GetStorageDriversAsync()).ToList(); + _variableTypes = (await VariableTypeService.GetVariableTypesAsync()).ToList(); + _groupedVariableTypes = _variableTypes.GroupBy(x => x.Category).ToList(); + + if (Output == null) + { + _model.Name = GetNewOutputName(WorkflowDefinition.Outputs); + _model.DisplayName = _model.Name.Humanize(); + _model.Type = _variableTypes.First(); + } + else + { + _model.Name = Output.Name; + _model.Type = _variableTypes.FirstOrDefault(x => x.TypeName == Output.Type) ?? _variableTypes.First(); + _model.IsArray = Output.IsArray; + _model.Description = Output.Description; + _model.Category = Output.Category; + _model.DisplayName = Output.DisplayName; + } + } + + private string GetNewOutputName(ICollection existingOutputs) + { + var count = 0; + + while (true) + { + var inputName = $"Output{++count}"; + + if (existingOutputs.All(x => x.Name != inputName)) + return inputName; + } + } + + private Task OnCancelClicked() + { + MudDialog.Cancel(); + return Task.CompletedTask; + } + + private async Task OnSubmitClicked() + { + if (!await _fluentValidationValidator.ValidateAsync()) + return; + + await OnValidSubmit(); + } + + private Task OnValidSubmit() + { + var output = Output ?? new OutputDefinition(); + + output.Name = _model.Name; + output.Type = _model.Type.TypeName; + output.IsArray = _model.IsArray; + output.Category = _model.Type.Category; + output.Description = _model.Description; + output.DisplayName = _model.DisplayName; + + MudDialog.Close(output); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/OutputsSection.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/OutputsSection.razor new file mode 100644 index 0000000..cd90bb1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/OutputsSection.razor @@ -0,0 +1,54 @@ +@using Variant = MudBlazor.Variant +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +@Localizer["Outputs"] + + + + @Localizer["Add output"] + + + @if (!Outputs.Any()) + { + @Localizer["There are currently no outputs defined."] + } + else + { + + + + @Localizer["Name"] + @Localizer["Type"] + + + + + + @foreach (var output in Outputs) + { + var typeDescriptor = output.Type != null ? _variableTypes.FirstOrDefault(x => x.TypeName == output.Type) : default; + var typeName = typeDescriptor?.DisplayName ?? output.Type; + if (output.IsArray) typeName += "[]"; + + @output.Name + @typeName + + + @Localizer["Edit"] + @Localizer["Delete"] + + + + } + + + } + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/OutputsSection.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/OutputsSection.razor.cs new file mode 100644 index 0000000..6bbee1a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Components/Outputs/OutputsSection.razor.cs @@ -0,0 +1,98 @@ +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.VariableTypes.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Contracts; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Outputs; + +public partial class OutputsSection +{ + private ICollection _variableTypes = new List(); + private ICollection _storageDriverDescriptors = new List(); + + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } + [Parameter] public bool IsReadonly { get; set; } = default; + [Inject] private IStorageDriverService StorageDriverService { get; set; } = default!; + [Inject] private IDialogService DialogService { get; set; } = default!; + [Inject] private IVariableTypeService VariableTypeService { get; set; } = default!; + + private ICollection Outputs => WorkflowDefinition.Outputs; + + protected override async Task OnInitializedAsync() + { + _storageDriverDescriptors = (await StorageDriverService.GetStorageDriversAsync()).ToList(); + } + + private StorageDriverDescriptor? GetStorageDriverDescriptor(string typeName) + { + return _storageDriverDescriptors.FirstOrDefault(x => x.TypeName == typeName); + } + + private async Task RaiseWorkflowDefinitionUpdatedAsync() + { + if (WorkflowDefinitionUpdated.HasDelegate) + await WorkflowDefinitionUpdated.InvokeAsync(); + } + + private async Task OpenOutputEditorDialog(OutputDefinition? outputDefinition) + { + var isNew = outputDefinition == null; + + var parameters = new DialogParameters + { + [nameof(EditOutputDialog.WorkflowDefinition)] = WorkflowDefinition + }; + + if (!isNew) + parameters[nameof(EditOutputDialog.Output)] = outputDefinition; + + var options = new DialogOptions + { + MaxWidth = MaxWidth.Medium, + FullWidth = true, + CloseButton = true, + CloseOnEscapeKey = true + }; + + var title = outputDefinition == null ? Localizer["Create output"] : Localizer["Edit output"]; + var dialog = await DialogService.ShowAsync(title, parameters, options); + var result = await dialog.Result; + + if (result.Canceled) + return; + + if (isNew) + { + outputDefinition = (OutputDefinition)result.Data; + WorkflowDefinition.Outputs.Add(outputDefinition); + } + + await RaiseWorkflowDefinitionUpdatedAsync(); + } + + private async Task OnEditClicked(OutputDefinition input) + { + await OpenOutputEditorDialog(input); + } + + private async Task OnDeleteClicked(OutputDefinition input) + { + var result = await DialogService.ShowMessageBox(Localizer["Delete selected output?"], Localizer["Are you sure you want to delete the selected output?"], yesText: Localizer["Delete"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + WorkflowDefinition.Outputs.Remove(input); + + await RaiseWorkflowDefinitionUpdatedAsync(); + } + + private async Task OnAddOutputClicked() + { + await OpenOutputEditorDialog(null); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/ArgumentDefinitionModel.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/ArgumentDefinitionModel.cs new file mode 100644 index 0000000..56d3fc5 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/ArgumentDefinitionModel.cs @@ -0,0 +1,13 @@ +using Elsa.Api.Client.Resources.VariableTypes.Models; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Models; + +public abstract class ArgumentDefinitionModel +{ + public VariableTypeDescriptor Type { get; set; } = default!; + public bool IsArray { get; set; } + public string Name { get; set; } = default!; + public string DisplayName { get; set; } = default!; + public string Description { get; set; } = default!; + public string Category { get; set; } = default!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/InputDefinitionModel.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/InputDefinitionModel.cs new file mode 100644 index 0000000..c3a8109 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/InputDefinitionModel.cs @@ -0,0 +1,11 @@ +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Models; + +public class InputDefinitionModel : ArgumentDefinitionModel +{ + public UIHintDescriptor? UIHint { get; set; } + + public StorageDriverDescriptor StorageDriver { get; set; } = default!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/OutputDefinitionModel.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/OutputDefinitionModel.cs new file mode 100644 index 0000000..7424088 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Models/OutputDefinitionModel.cs @@ -0,0 +1,5 @@ +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Models; + +public class OutputDefinitionModel : ArgumentDefinitionModel +{ +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Validators/InputModelValidator.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Validators/InputModelValidator.cs new file mode 100644 index 0000000..c1a1667 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Validators/InputModelValidator.cs @@ -0,0 +1,23 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Models; +using FluentValidation; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Validators; + +public class InputModelValidator : AbstractValidator +{ + public InputModelValidator(WorkflowDefinition workflowDefinition, ILocalizer localizer) + { + RuleFor(x => x.Name).NotEmpty().WithMessage(localizer["Please enter a name for the input."]); + + RuleFor(x => x.Name) + .Must((context, name, cancellationToken) => + { + var existingInput = workflowDefinition.Inputs.FirstOrDefault(x => x.Name == name); + return existingInput == null || existingInput.Name == context.Name; + }) + .WithMessage(localizer["An input with this name already exists."]); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Validators/OutputModelValidator.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Validators/OutputModelValidator.cs new file mode 100644 index 0000000..cb930df --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/InputOutput/Validators/OutputModelValidator.cs @@ -0,0 +1,23 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Models; +using FluentValidation; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Validators; + +public class OutputModelValidator : AbstractValidator +{ + public OutputModelValidator(WorkflowDefinition workflowDefinition, ILocalizer localizer) + { + RuleFor(x => x.Name).NotEmpty().WithMessage(localizer["Please enter a name for the output."]); + + RuleFor(x => x.Name) + .Must((context, name, cancellationToken) => + { + var existingOutput = workflowDefinition.Outputs.FirstOrDefault(x => x.Name == name); + return existingOutput == null || existingOutput.Name == context.Name; + }) + .WithMessage(localizer["An input with this name already exists."]); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/PropertiesTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/PropertiesTab.razor new file mode 100644 index 0000000..2d33083 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/PropertiesTab.razor @@ -0,0 +1,6 @@ +@using Elsa.Studio.Extensions + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/PropertiesTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/PropertiesTab.razor.cs new file mode 100644 index 0000000..b1b1cf2 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/PropertiesTab.razor.cs @@ -0,0 +1,24 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Properties; + +/// +/// A component that renders the workflow definition properties tab. +/// +public partial class PropertiesTab +{ + /// + /// Gets or sets the workflow definition. + /// + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + + /// + /// Gets or sets the callback that is invoked when the workflow definition is updated. + /// + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } + + [CascadingParameter] private IWorkspace? Workspace { get; set; } + private bool IsReadOnly => Workspace?.IsReadOnly ?? false; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Info/Info.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Info/Info.razor new file mode 100644 index 0000000..17bdea3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Info/Info.razor @@ -0,0 +1,4 @@ +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@Localizer["Information"] + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Info/Info.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Info/Info.razor.cs new file mode 100644 index 0000000..43d2b6f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Info/Info.razor.cs @@ -0,0 +1,26 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Properties. + Sections.Info; + +public partial class Info +{ + private DataPanelModel _workflowInfo = new (); + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = null!; + + /// + protected override void OnParametersSet() + { + _workflowInfo = + [ + new DataPanelItem(Localizer["Definition ID"], WorkflowDefinition.DefinitionId), + new DataPanelItem(Localizer["Version ID"], WorkflowDefinition.Id), + new DataPanelItem(Localizer["Version"], WorkflowDefinition.Version.ToString()), + new DataPanelItem(Localizer["Status"], WorkflowDefinition.IsPublished ? Localizer["Published"] : Localizer["Draft"]), + new DataPanelItem(Localizer["Readonly"], WorkflowDefinition.IsReadonly ? Localizer["Yes"] : Localizer["No"]) + ]; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Metadata/Metadata.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Metadata/Metadata.razor new file mode 100644 index 0000000..bba53b0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Metadata/Metadata.razor @@ -0,0 +1,15 @@ +@using Elsa.Studio.Workflows.Services +@using Variant = MudBlazor.Variant +@using Microsoft.Extensions.Localization +@inject ILocalizer Localizer + +
+ @Localizer["Metadata"] + + + + + + + +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Metadata/Metadata.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Metadata/Metadata.razor.cs new file mode 100644 index 0000000..96a1ae9 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Metadata/Metadata.razor.cs @@ -0,0 +1,59 @@ +using Blazored.FluentValidation; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.Validators; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Properties.Sections.Metadata; + +/// +/// A component that renders the workflow definition metadata. +/// +public partial class Metadata +{ + private readonly WorkflowMetadataModel _model = new(); + private FluentValidationValidator _fluentValidationValidator = default!; + private WorkflowPropertiesModelValidator _validator = default!; + private EditContext _editContext = default!; + + /// + /// Gets or sets the workflow definition. + /// + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + + /// + /// Gets or sets the callback that is invoked when the workflow definition is updated. + /// + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } + [CascadingParameter] private IWorkspace? Workspace { get; set; } + + private bool IsReadOnly => Workspace?.IsReadOnly ?? false; + + /// + protected override void OnParametersSet() + { + _model.DefinitionId = WorkflowDefinition.DefinitionId; + _model.Description = WorkflowDefinition.Description; + _model.Name = WorkflowDefinition.Name; + _editContext = new EditContext(_model); + } + + private async Task ValidateForm() + { + if (!await _fluentValidationValidator.ValidateAsync()) + return; + + await OnValidSubmit(); + } + + private async Task OnValidSubmit() + { + WorkflowDefinition.Description = _model.Description; + WorkflowDefinition.Name = _model.Name; + + if (WorkflowDefinitionUpdated.HasDelegate) + await WorkflowDefinitionUpdated.InvokeAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Settings/Settings.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Settings/Settings.razor new file mode 100644 index 0000000..dc0f246 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Settings/Settings.razor @@ -0,0 +1,122 @@ +@using Elsa.Api.Client.Resources.CommitStrategies.Models +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Resources.WorkflowActivationStrategies.Models +@using Elsa.Api.Client.Resources.IncidentStrategies.Models +@using Elsa.Api.Client.Resources.LogPersistenceStrategies +@inherits StudioComponentBase +@inject ILocalizer Localizer + +@if (WorkflowDefinition != null) +{ +
+ @Localizer["Settings"] + + + @foreach (var strategy in _activationStrategies) + { + @strategy.DisplayName + } + + + @foreach (var strategy in _incidentStrategies) + { + @(strategy?.DisplayName ?? @Localizer["Default"]) + } + + + + @foreach (var strategy in _logPersistenceStrategyDescriptors) + { + @(strategy?.DisplayName ?? "Inherit") + } + + + + @Localizer["Commit Strategy"] + + + @foreach (var strategy in _commitStrategies) + { + @(string.IsNullOrWhiteSpace(strategy?.DisplayName) ? Localizer["Default"] : strategy.DisplayName) + } + + + @Localizer["Activity"] + + + + + @if (WorkflowDefinition.Options.UsableAsActivity == true) + { + + + + + } + +
+} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Settings/Settings.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Settings/Settings.razor.cs new file mode 100644 index 0000000..43ef231 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Properties/Sections/Settings/Settings.razor.cs @@ -0,0 +1,192 @@ +using Elsa.Api.Client.Resources.IncidentStrategies.Models; +using Elsa.Api.Client.Resources.WorkflowActivationStrategies.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Enums; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; +using System.Text.Json; +using Elsa.Api.Client.Resources.CommitStrategies.Models; +using Elsa.Api.Client.Resources.LogPersistenceStrategies; +using Elsa.Api.Client.Resources.Scripting.Models; +using Elsa.Api.Client.Serialization; +using Elsa.Api.Client.Shared.Enums; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Properties.Sections.Settings; + +/// +/// Displays the settings of a workflow. +/// +public partial class Settings +{ + private readonly JsonSerializerOptions _serializerOptions = SerializerOptions.LogPersistenceConfigSerializerOptions; + + /// + /// The workflow definition. + /// + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// + /// An event raised when the workflow is updated. + /// + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } + + /// + /// The workspace. + /// + [CascadingParameter] public IWorkspace? Workspace { get; set; } + + [Inject] private IWorkflowActivationStrategyService WorkflowActivationStrategyService { get; set; } = null!; + [Inject] private IIncidentStrategiesProvider IncidentStrategiesProvider { get; set; } = null!; + [Inject] private ILogPersistenceStrategyService LogPersistenceStrategyService { get; set; } = null!; + [Inject] private ICommitStrategiesProvider CommitStrategiesProvider { get; set; } = null!; + + private bool IsReadOnly => Workspace?.IsReadOnly ?? false; + private ICollection _activationStrategies = new List(); + private ICollection _incidentStrategies = new List(); + private ICollection _logPersistenceStrategyDescriptors = new List(); + private ICollection _commitStrategies = new List(); + private WorkflowActivationStrategyDescriptor? _selectedActivationStrategy; + private IncidentStrategyDescriptor? _selectedIncidentStrategy; + private LogPersistenceStrategyDescriptor? _selectedLogPersistenceStrategy; + private LogPersistenceConfiguration? _logPersistenceConfiguration; + private CommitStrategyDescriptor? _selectedCommitStrategy; + private ExpressionEditor _logPersistenceExpressionEditor = null!; + + /// + protected override async Task OnInitializedAsync() + { + _activationStrategies = (await WorkflowActivationStrategyService.GetWorkflowActivationStrategiesAsync()).ToList(); + var incidentStrategies = (await IncidentStrategiesProvider.GetIncidentStrategiesAsync()).ToList(); + var commitStrategies = (await CommitStrategiesProvider.GetWorkflowCommitStrategiesAsync()).ToList(); + _incidentStrategies = new IncidentStrategyDescriptor?[] { null }.Concat(incidentStrategies).ToList(); + _commitStrategies = new CommitStrategyDescriptor?[] { null }.Concat(commitStrategies).ToList(); + _logPersistenceStrategyDescriptors = (await LogPersistenceStrategyService.GetLogPersistenceStrategiesAsync()).ToList(); + _selectedActivationStrategy = _activationStrategies.FirstOrDefault(x => x.TypeName == WorkflowDefinition!.Options.ActivationStrategyType) ?? _activationStrategies.FirstOrDefault(); + _selectedIncidentStrategy = _incidentStrategies.FirstOrDefault(x => x?.TypeName == WorkflowDefinition!.Options.IncidentStrategyType) ?? _incidentStrategies.FirstOrDefault(); + _selectedCommitStrategy = _commitStrategies.FirstOrDefault(x => x?.Name == WorkflowDefinition!.Options.CommitStrategyName) ?? _commitStrategies.FirstOrDefault(); + _logPersistenceConfiguration = GetLogPersistenceConfiguration(); + _selectedLogPersistenceStrategy = _logPersistenceStrategyDescriptors.FirstOrDefault(x => x.TypeName == _logPersistenceConfiguration?.StrategyType) ?? _logPersistenceStrategyDescriptors.FirstOrDefault(); + await _logPersistenceExpressionEditor.UpdateAsync(_logPersistenceConfiguration?.Expression); + } + + private LogPersistenceMode? GetLegacyGetLogPersistenceMode() + { + if (WorkflowDefinition!.CustomProperties.TryGetValue("logPersistenceMode", out var value) && value != null!) + { + var persistenceString = ((JsonElement)value).GetProperty("default"); + return (LogPersistenceMode)Enum.Parse(typeof(LogPersistenceMode), persistenceString.ToString()); + } + + return null; + } + + private LogPersistenceConfiguration? GetLogPersistenceConfiguration() + { + if (WorkflowDefinition!.CustomProperties.TryGetValue("logPersistenceConfig", out var value) && value != null!) + { + var configJson = ((JsonElement)value).GetProperty("default"); + var config = JsonSerializer.Deserialize(configJson, _serializerOptions); + return config; + } + + var legacyMode = GetLegacyGetLogPersistenceMode(); + var strategyDescriptor = _logPersistenceStrategyDescriptors.FirstOrDefault(x => x.DisplayName == legacyMode.ToString()) ?? _logPersistenceStrategyDescriptors.FirstOrDefault(); + return new() + { + EvaluationMode = LogPersistenceEvaluationMode.Strategy, + StrategyType = strategyDescriptor?.TypeName + }; + } + + private async Task RaiseWorkflowUpdatedAsync() + { + if (WorkflowDefinitionUpdated.HasDelegate) + await WorkflowDefinitionUpdated.InvokeAsync(); + } + + private async Task UpdateLogPersistenceConfigAsync(LogPersistenceConfiguration newConfig) + { + _logPersistenceConfiguration = newConfig; + var dictionary = new Dictionary { { "default", newConfig } }; + var dictionaryJson = JsonSerializer.SerializeToElement(dictionary, _serializerOptions); + WorkflowDefinition!.CustomProperties["logPersistenceConfig"] = dictionaryJson; + await RaiseWorkflowUpdatedAsync(); + } + + private IDictionary GetExpressionEditorProps() + { + var props = new Dictionary + { + ["WorkflowDefinitionId"] = WorkflowDefinition!.DefinitionId + }; + + return props; + } + + private async Task OnActivationStrategyChanged(WorkflowActivationStrategyDescriptor value) + { + _selectedActivationStrategy = value; + WorkflowDefinition!.Options.ActivationStrategyType = value.TypeName; + await RaiseWorkflowUpdatedAsync(); + } + + private async Task OnIncidentStrategyChanged(IncidentStrategyDescriptor? value) + { + _selectedIncidentStrategy = value; + WorkflowDefinition!.Options.IncidentStrategyType = value?.TypeName; + await RaiseWorkflowUpdatedAsync(); + } + + private async Task OnLogPersistenceStrategySelectionChanged(LogPersistenceStrategyDescriptor? value) + { + _selectedLogPersistenceStrategy = value; + var currentConfig = _logPersistenceConfiguration; + var newConfig = new LogPersistenceConfiguration + { + EvaluationMode = LogPersistenceEvaluationMode.Strategy, + StrategyType = value?.TypeName, + Expression = currentConfig?.Expression + }; + await UpdateLogPersistenceConfigAsync(newConfig); + } + + private async Task OnLogPersistenceExpressionChanged(Expression? value) + { + var currentConfig = _logPersistenceConfiguration; + var newConfig = new LogPersistenceConfiguration + { + EvaluationMode = LogPersistenceEvaluationMode.Expression, + StrategyType = currentConfig?.StrategyType, + Expression = value + }; + await UpdateLogPersistenceConfigAsync(newConfig); + } + + private async Task OnUsableAsActivityCheckChanged(bool? value) + { + WorkflowDefinition!.Options.UsableAsActivity = value; + await RaiseWorkflowUpdatedAsync(); + } + + private async Task OnAutoUpdateConsumingWorkflowsCheckChanged(bool? value) + { + WorkflowDefinition!.Options.AutoUpdateConsumingWorkflows = value == true; + await RaiseWorkflowUpdatedAsync(); + } + + private async Task OnCategoryChanged(string value) + { + WorkflowDefinition!.Options.ActivityCategory = value; + await RaiseWorkflowUpdatedAsync(); + } + + private async Task OnCommitStrategySelectionChanged(CommitStrategyDescriptor? value) + { + _selectedCommitStrategy = value; + WorkflowDefinition!.Options.CommitStrategyName = value?.Name; + await RaiseWorkflowUpdatedAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/EditVariableDialog.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/EditVariableDialog.razor new file mode 100644 index 0000000..47f9d01 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/EditVariableDialog.razor @@ -0,0 +1,44 @@ +@using Variant = MudBlazor.Variant +@using Elsa.Api.Client.Resources.StorageDrivers.Models +@using Elsa.Api.Client.Resources.VariableTypes.Models +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@inherits StudioComponentBase + + + + + + + @_model.Id + + + @foreach (var grouping in _groupedVariableTypes) + { + + @foreach (var variableType in grouping) + { + @variableType.DisplayName + } + + } + + + + + + + @foreach (var storageDriver in _storageDriverDescriptors) + { + var displayName = storageDriver.Deprecated ? $"{storageDriver.DisplayName} (Deprecated)" : storageDriver.DisplayName; + @displayName + } + + + + + + @Localizer["Cancel"] + @Localizer["Ok"] + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/EditVariableDialog.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/EditVariableDialog.razor.cs new file mode 100644 index 0000000..fbbfca5 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/EditVariableDialog.razor.cs @@ -0,0 +1,110 @@ +using Blazored.FluentValidation; +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.VariableTypes.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Variables.Models; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Variables.Validators; +using Elsa.Studio.Workflows.Domain.Contracts; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Variables.Components; + +/// +/// A dialog that allows the user to edit a variable. +/// +public partial class EditVariableDialog +{ + private readonly VariableModel _model = new(); + private EditContext _editContext = null!; + private VariableModelValidator _validator = null!; + private FluentValidationValidator _fluentValidationValidator = null!; + private ICollection _storageDriverDescriptors = new List(); + private ICollection _variableTypes = new List(); + private ICollection> _groupedVariableTypes = new List>(); + + /// + /// The workflow definition that the variable belongs to. + /// + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = null!; + /// + /// The variable to edit. If null, a new variable will be created. + /// + [Parameter] public Variable? Variable { get; set; } + [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!; + [Inject] private IStorageDriverService StorageDriverService { get; set; } = null!; + [Inject] private IVariableTypeService VariableTypeService { get; set; } = null!; + [Inject] private IIdentityGenerator IdentityGenerator { get; set; } = null!; + + /// + protected override async Task OnParametersSetAsync() + { + // Instantiate the edit context first, so that it is available when rendering (which happens as soon as we call an async method on the next lines). + _editContext = new(_model); + _validator = new(WorkflowDefinition, Localizer); + + _storageDriverDescriptors = (await StorageDriverService.GetStorageDriversAsync()).OrderByDescending(x => x.Priority).ToList(); + _variableTypes = (await VariableTypeService.GetVariableTypesAsync()).ToList(); + _groupedVariableTypes = _variableTypes.GroupBy(x => x.Category).ToList(); + + if (Variable == null) + { + _model.Id = IdentityGenerator.GenerateId(); + _model.Name = GetNewVariableName(WorkflowDefinition.Variables); + _model.StorageDriver = _storageDriverDescriptors.First(); + _model.VariableType = _variableTypes.First(); + } + else + { + _model.Id = Variable.Id; + _model.Name = Variable.Name; + _model.VariableType = _variableTypes.FirstOrDefault(x => x.TypeName == Variable.TypeName) ?? _variableTypes.First(); + _model.DefaultValue = Variable.Value?.ToString() ?? ""; + _model.IsArray = Variable.IsArray; + _model.StorageDriver = _storageDriverDescriptors.FirstOrDefault(x => x.TypeName == Variable.StorageDriverTypeName) ?? _storageDriverDescriptors.First(); + } + } + + private string GetNewVariableName(ICollection existingVariables) + { + var count = 0; + + while (true) + { + var variableName = $"Variable{++count}"; + + if (existingVariables.All(x => x.Name != variableName)) + return variableName; + } + } + + private Task OnCancelClicked() + { + MudDialog.Cancel(); + return Task.CompletedTask; + } + + private async Task OnSubmitClicked() + { + if (!await _fluentValidationValidator.ValidateAsync()) + return; + + await OnValidSubmit(); + } + + private Task OnValidSubmit() + { + var variable = Variable ?? new Variable(); + + variable.Id = _model.Id; + variable.Name = _model.Name; + variable.TypeName = _model.VariableType.TypeName; + variable.Value = _model.DefaultValue; + variable.IsArray = _model.IsArray; + variable.StorageDriverTypeName = _model.StorageDriver.TypeName; + + MudDialog.Close(variable); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/VariablesTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/VariablesTab.razor new file mode 100644 index 0000000..892c733 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/VariablesTab.razor @@ -0,0 +1,60 @@ +@using Variant = MudBlazor.Variant +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@inherits StudioComponentBase + + + + @Localizer["Variables"] + + + + @Localizer["Add variable"] + + + @if (!Variables.Any()) + { + @Localizer["There are currently no variables defined."] + } + else + { + + + + + @Localizer["Name"] + @Localizer["Type"] + @Localizer["Storage"] + + + + + + @foreach (var variable in Variables) + { + var storageDescriptor = variable.StorageDriverTypeName != null ? GetStorageDriverDescriptor(variable.StorageDriverTypeName) : default; + var storageDriverName = storageDescriptor != null ? storageDescriptor.DisplayName : @Localizer["None"]; + + @variable.Name + @variable.GetTypeDisplayName() + @storageDriverName + + + @Localizer["Edit"] + @Localizer["Delete"] + + + + } + + + + } + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/VariablesTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/VariablesTab.razor.cs new file mode 100644 index 0000000..1e6d41e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Components/VariablesTab.razor.cs @@ -0,0 +1,98 @@ +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components.Outputs; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Variables.Components; + +public partial class VariablesTab +{ + private ICollection _storageDriverDescriptors = new List(); + + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } + [CascadingParameter] public IWorkspace? Workspace { get; set; } + [Inject] IStorageDriverService StorageDriverService { get; set; } = default!; + [Inject] IDialogService DialogService { get; set; } = default!; + + private bool IsReadOnly => Workspace?.IsReadOnly ?? true; + private ICollection Variables => WorkflowDefinition.Variables; + + protected override async Task OnInitializedAsync() + { + _storageDriverDescriptors = (await StorageDriverService.GetStorageDriversAsync()).ToList(); + } + + private StorageDriverDescriptor? GetStorageDriverDescriptor(string typeName) + { + return _storageDriverDescriptors.FirstOrDefault(x => x.TypeName == typeName); + } + + private async Task RaiseWorkflowDefinitionUpdatedAsync() + { + if (WorkflowDefinitionUpdated.HasDelegate) + await WorkflowDefinitionUpdated.InvokeAsync(); + } + + private async Task OpenVariableEditorDialog(Variable? variable) + { + var isNew = variable == null; + + var parameters = new DialogParameters + { + [nameof(EditVariableDialog.WorkflowDefinition)] = WorkflowDefinition + }; + + if (!isNew) + parameters[nameof(EditVariableDialog.Variable)] = variable; + + var options = new DialogOptions + { + MaxWidth = MaxWidth.Medium, + FullWidth = true, + CloseButton = true, + CloseOnEscapeKey = true + }; + + var title = variable == null ? Localizer["Create variable"] : Localizer["Edit variable"]; + var dialog = await DialogService.ShowAsync(title, parameters, options); + var result = await dialog.Result; + + if (result.Canceled) + return; + + if (isNew) + { + variable = (Variable)result.Data; + WorkflowDefinition.Variables.Add(variable); + } + + await RaiseWorkflowDefinitionUpdatedAsync(); + } + + private async Task OnEditClicked(Variable variable) + { + await OpenVariableEditorDialog(variable); + } + + private async Task OnDeleteClicked(Variable variable) + { + var result = await DialogService.ShowMessageBox(Localizer["Delete selected variable?"], Localizer["Are you sure you want to delete the selected variable?"], yesText: Localizer["Delete"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + WorkflowDefinition.Variables.Remove(variable); + + await RaiseWorkflowDefinitionUpdatedAsync(); + } + + private async Task OnAddVariableClicked() + { + await OpenVariableEditorDialog(null); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Models/VariableModel.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Models/VariableModel.cs new file mode 100644 index 0000000..3ad494c --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Models/VariableModel.cs @@ -0,0 +1,14 @@ +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.VariableTypes.Models; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Variables.Models; + +public class VariableModel +{ + public string Id { get; set; } = default!; + public string Name { get; set; } = default!; + public VariableTypeDescriptor VariableType { get; set; } = default!; + public bool IsArray { get; set; } + public string? DefaultValue { get; set; } + public StorageDriverDescriptor StorageDriver { get; set; } = default!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Validators/VariableModelValidator.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Validators/VariableModelValidator.cs new file mode 100644 index 0000000..9d9fd80 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/Variables/Validators/VariableModelValidator.cs @@ -0,0 +1,26 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Variables.Models; +using FluentValidation; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Variables.Validators; + +/// +/// Validates a variable model. +/// +public class VariableModelValidator : AbstractValidator +{ + public VariableModelValidator(WorkflowDefinition workflowDefinition, ILocalizer localizer) + { + RuleFor(x => x.Name).NotEmpty().WithMessage(localizer["Please enter a name for the variable."]); + + RuleFor(x => x.Name) + .Must((context, name, cancellationToken) => + { + var existingVariable = workflowDefinition.Variables.FirstOrDefault(x => x.Name == name && x.Id != context.Id); + return existingVariable == null || existingVariable.Id == context.Name; + }) + .WithMessage(localizer["A variable with this name already exists in the current scope."]); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/VersionHistory/VersionHistoryTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/VersionHistory/VersionHistoryTab.razor new file mode 100644 index 0000000..9dd5d68 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/VersionHistory/VersionHistoryTab.razor @@ -0,0 +1,60 @@ +@using Elsa.Api.Client.Resources.WorkflowDefinitions.Models +@using Variant = MudBlazor.Variant +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@inherits StudioComponentBase +
+ + @Localizer["Version history"] + + + @Localizer["Delete"] + + + + + @Localizer["Published"] + @Localizer["Version"] + @Localizer["Created"] + + + + + @if (context.IsPublished) + { + + } + + @context.Version + @context.CreatedAt.ToString("g") + + + @Localizer["View"] + @Localizer["Rollback to this version"] + @Localizer["Delete"] + + + + + + + + + + +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/VersionHistory/VersionHistoryTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/VersionHistory/VersionHistoryTab.razor.cs new file mode 100644 index 0000000..6e3cae3 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/Tabs/VersionHistory/VersionHistoryTab.razor.cs @@ -0,0 +1,144 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Enums; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Domain.Notifications; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.VersionHistory; + +/// Represents a tab in the version history section of a workflow definition workspace. +public partial class VersionHistoryTab : IDisposable +{ + /// Gets or sets the definition ID. + [Parameter] public string DefinitionId { get; set; } = default!; + + [CascadingParameter] private WorkflowDefinitionWorkspace Workspace { get; set; } = default!; + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = default!; + [Inject] private IWorkflowDefinitionHistoryService WorkflowDefinitionHistoryService { get; set; } = default!; + [Inject] private IDialogService DialogService { get; set; } = default!; + [Inject] private IMediator Mediator { get; set; } = default!; + + private HashSet SelectedDefinitions { get; set; } = new(); + private MudTable Table { get; set; } = default!; + private bool IsReadOnly => Workspace.IsReadOnly; + private bool HasWorkflowEditPermission => Workspace.HasWorkflowEditPermission; + private long _recordCount = 0; + + /// + protected override void OnInitialized() + { + Workspace.WorkflowDefinitionUpdated += OnWorkflowDefinitionUpdated; + } + + void IDisposable.Dispose() + { + Workspace.WorkflowDefinitionUpdated -= OnWorkflowDefinitionUpdated; + } + + private async Task> LoadVersionsAsync(TableState tableState, CancellationToken cancellationToken) + { + var page = tableState.Page; + var pageSize = tableState.PageSize; + + var request = new ListWorkflowDefinitionsRequest + { + DefinitionIds = [DefinitionId], + OrderDirection = OrderDirection.Descending, + OrderBy = OrderByWorkflowDefinition.Version, + Page = page, + PageSize = pageSize + }; + + var response = await WorkflowDefinitionService.ListAsync(request, VersionOptions.All); + + _recordCount = response.TotalCount; + return new TableData + { + Items = response.Items, + TotalItems = (int)response.TotalCount + }; + } + + private async Task ViewVersionAsync(WorkflowDefinitionSummary workflowDefinitionSummary) + { + var workflowDefinition = (await WorkflowDefinitionService.FindByIdAsync(workflowDefinitionSummary.Id))!; + await Workspace.DisplayWorkflowDefinitionVersionAsync(workflowDefinition); + } + + private async Task ReloadTableAsync() + { + await Table.ReloadServerData(); + } + + private bool CanRollback(WorkflowDefinitionSummary workflowDefinitionSummary) + { + return HasWorkflowEditPermission && workflowDefinitionSummary is { IsLatest: false }; + } + + private bool CanDelete(WorkflowDefinitionSummary workflowDefinitionSummary) + { + return HasWorkflowEditPermission && _recordCount > 1; + } + + private async Task OnWorkflowDefinitionUpdated() => await ReloadTableAsync(); + + private async Task OnViewClicked(WorkflowDefinitionSummary workflowDefinitionSummary) + { + await ViewVersionAsync(workflowDefinitionSummary); + } + + private async Task OnDeleteClicked(WorkflowDefinitionSummary workflowDefinitionSummary) + { + var confirmed = await DialogService.ShowMessageBox(Localizer["Delete version {0}", workflowDefinitionSummary.Version], Localizer["Are you sure you want to delete this version?"]); + + if (confirmed != true) + return; + + var workflowDefinitionVersion = WorkflowDefinitionVersion.FromDefinitionSummary(workflowDefinitionSummary); + await WorkflowDefinitionService.DeleteVersionAsync(workflowDefinitionVersion); + await ReloadTableAsync(); + + if (Workspace.IsSelectedDefinition(workflowDefinitionVersion.WorkflowDefinitionVersionId)) + await Workspace.DisplayLatestWorkflowDefinitionVersionAsync(); + } + + private async Task OnRowClick(TableRowClickEventArgs arg) + { + await ViewVersionAsync(arg.Item); + } + + private async Task OnBulkDeleteClicked() + { + var confirmed = await DialogService.ShowMessageBox(Localizer["Delete selected versions"], Localizer["Are you sure you want to delete the selected versions?"]); + + if (confirmed != true) + return; + + var definitionVersions = SelectedDefinitions.Select(WorkflowDefinitionVersion.FromDefinitionSummary).ToList(); + await WorkflowDefinitionService.BulkDeleteVersionsAsync(definitionVersions); + await ReloadTableAsync(); + + var selectedDefinition = Workspace.GetSelectedDefinition(); + if (selectedDefinition != null && definitionVersions.Any(x => x.WorkflowDefinitionVersionId == selectedDefinition.Id)) + await Workspace.DisplayLatestWorkflowDefinitionVersionAsync(); + } + + private async Task OnRollbackClicked(WorkflowDefinitionSummary workflowDefinitionSummary) + { + var definitionVersionId = workflowDefinitionSummary.Id; + var definitionId = workflowDefinitionSummary.DefinitionId; + var version = workflowDefinitionSummary.Version; + var revertingVersion = new WorkflowDefinitionVersion(definitionId, definitionVersionId, version); + var newDefinitionVersion = await WorkflowDefinitionHistoryService.RevertAsync(revertingVersion); + await ReloadTableAsync(); + var newWorkflowDefinition = (await WorkflowDefinitionService.FindByIdAsync(newDefinitionVersion.Id))!; + await Workspace.DisplayWorkflowDefinitionVersionAsync(newWorkflowDefinition); + await Mediator.NotifyAsync(new WorkflowDefinitionReverted(newWorkflowDefinition)); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/WorkflowProperties.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/WorkflowProperties.razor new file mode 100644 index 0000000..f9483ce --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/WorkflowProperties.razor @@ -0,0 +1,23 @@ +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Properties +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Variables.Components +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.InputOutput.Components +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.VersionHistory +@using Elsa.Studio.Workflows.Shared.Args +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@inherits StudioComponentBase + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/WorkflowProperties.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/WorkflowProperties.razor.cs new file mode 100644 index 0000000..cf4c0d5 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/WorkflowProperties/WorkflowProperties.razor.cs @@ -0,0 +1,10 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties; + +public partial class WorkflowProperties +{ + [Parameter] public WorkflowDefinition WorkflowDefinition { get; set; } = default!; + [Parameter] public EventCallback WorkflowDefinitionUpdated { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/WorkflowDefinitionEditor.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/WorkflowDefinitionEditor.razor new file mode 100644 index 0000000..f491667 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/WorkflowDefinitionEditor.razor @@ -0,0 +1,69 @@ +@using System.Text.Json.Nodes +@using Orientation = Radzen.Orientation +@using Elsa.Studio.Workflows.Models +@using Elsa.Api.Client.Resources.WorkflowDefinitions.Models +@using Elsa.Api.Client.Shared.Models +@using Elsa.Studio.Workflows.Domain.Contracts +@using Elsa.Studio.Workflows.Extensions +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +@inject IWorkflowDefinitionService WorkflowDefinitionService + +@if (IsReadOnly) +{ + @Localizer["Unable to make changes as the workflow or application is currently in read-only mode"]. +} + + + + + + + + + + + + +@code +{ + private readonly DragDropManager _dragDropManager = new(); + private WorkflowDefinition? _workflowDefinition; + private WorkflowDefinitionWorkspace WorkflowDefinitionWorkspace { get; set; } = null!; + + /// The ID of the workflow definition to load. + [Parameter] public string DefinitionId { get; set; } = null!; + + /// Gets or sets the event that occurs when the workflow definition version is updated. + [Parameter] public Func? WorkflowDefinitionVersionSelected { get; set; } + + /// Gets or sets the event triggered when an activity is selected. + [Parameter] public Func? ActivitySelected { get; set; } + + /// Gets the currently selected workflow definition version. + public WorkflowDefinition? GetSelectedWorkflowDefinitionVersion() => WorkflowDefinitionWorkspace.GetSelectedWorkflowDefinitionVersion(); + + /// An event that is invoked when a workflow definition has been executed. + /// The ID of the workflow instance is provided as the value to the event callback. + [Parameter] public Func? WorkflowDefinitionExecuted { get; set; } + + /// Gets the currently selected activity ID. + public string? SelectedActivityId => WorkflowDefinitionWorkspace.SelectedActivityId; + + /// Gets a value that indicates if the workflow definition editor should be displayed in readonly mode. + private bool IsReadOnly => _workflowDefinition.GetIsReadOnly(); + + /// + protected override async Task OnParametersSetAsync() + { + _workflowDefinition = await WorkflowDefinitionService.FindByDefinitionIdAsync(DefinitionId, VersionOptions.Latest); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/CreateWorkflowDialog.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/CreateWorkflowDialog.razor new file mode 100644 index 0000000..7c4c3c7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/CreateWorkflowDialog.razor @@ -0,0 +1,20 @@ +@using Variant = MudBlazor.Variant +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + + + + + + + + + + + + + @Localizer["Cancel"] + @Localizer["Ok"] + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/CreateWorkflowDialog.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/CreateWorkflowDialog.razor.cs new file mode 100644 index 0000000..ac423f4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/CreateWorkflowDialog.razor.cs @@ -0,0 +1,56 @@ +using Blazored.FluentValidation; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.Validators; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionList; + +/// +/// A dialog that allows the user to create a new workflow. +/// +public partial class CreateWorkflowDialog +{ + private readonly WorkflowMetadataModel _metadataModel = new(); + private EditContext _editContext = null!; + private WorkflowPropertiesModelValidator _validator = null!; + private FluentValidationValidator _fluentValidationValidator = null!; + + /// + /// The name of the workflow to create. + /// + [Parameter] public string WorkflowName { get; set; } = "New workflow"; + [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!; + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = null!; + + /// + protected override void OnParametersSet() + { + _metadataModel.Name = WorkflowName; + _editContext = new(_metadataModel); + _validator = new(WorkflowDefinitionService, Localizer); + } + + private Task OnCancelClicked() + { + MudDialog.Cancel(); + return Task.CompletedTask; + } + + private async Task OnSubmitClicked() + { + if(!await _fluentValidationValidator.ValidateAsync()) + return; + + await OnValidSubmit(); + } + + private Task OnValidSubmit() + { + MudDialog.Close(_metadataModel); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/WorkflowDefinitionList.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/WorkflowDefinitionList.razor new file mode 100644 index 0000000..b8d8b16 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/WorkflowDefinitionList.razor @@ -0,0 +1,142 @@ +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@using Variant = MudBlazor.Variant +@using Microsoft.Extensions.Localization +@inject ILocalizer Localizer + +@if (IsReadOnlyMode) +{ + @Localizer["You are running in read-only mode. Workflow operations are disabled"]. +} + + + + +
+ +
+ + + + + @Localizer["Delete"] + @Localizer["Publish"] + @Localizer["Unpublish"] + @Localizer["Export"] + + + + + + + @Localizer["Create workflow"] + + + @Localizer["Import"] + + + + + + + @Localizer["Definition ID"] + + + @Localizer["Name"] + + + @Localizer["Latest version"] + + + @Localizer["Published version"] + + + @Localizer["Description"] + + + + + @context.DefinitionId + + +
+ @context.Name +
+
+
+ @context.LatestVersion + @(context.PublishedVersion?.ToString() ?? "-") + + +
+ @context.Description +
+
+
+ + + @if (!IsReadOnlyMode && !context.IsReadOnlyMode) + { + @Localizer["Edit"] + } + else + { + @Localizer["View"] + } + @Localizer["Run"] + @Localizer["Delete"] + @Localizer["Cancel"] + + @Localizer["Publish"] + @Localizer["Unpublish"] + + @Localizer["Export"] + + + +
+ + @Localizer["No workflow definitions found"] + + + @Localizer["Loading"]... + + + + +
+
+ + diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/WorkflowDefinitionList.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/WorkflowDefinitionList.razor.cs new file mode 100644 index 0000000..3aaebd8 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionList/WorkflowDefinitionList.razor.cs @@ -0,0 +1,402 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Enums; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Requests; +using Elsa.Api.Client.Resources.WorkflowInstances.Requests; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.DomInterop.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Models; +using Humanizer; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using Microsoft.JSInterop; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionList; + +/// Displays a list of workflow definitions. +public partial class WorkflowDefinitionList +{ + private MudTable _table = null!; + private HashSet _selectedRows = new(); + private long _totalCount; + + /// An event that is invoked when a workflow definition is edited. + [Parameter] public EventCallback EditWorkflowDefinition { get; set; } + + [Inject] private IDialogService DialogService { get; set; } = default!; + [Inject] private NavigationManager navigation { get; set; } + [Inject] private ISnackbar Snackbar { get; set; } = default!; + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = default!; + [Inject] private IWorkflowInstanceService WorkflowInstanceService { get; set; } = default!; + [Inject] private IWorkflowDefinitionImporter WorkflowDefinitionImporter { get; set; } = default!; + [Inject] private IFiles Files { get; set; } = default!; + [Inject] private IDomAccessor DomAccessor { get; set; } = default!; + [Inject] private IMediator Mediator { get; set; } = default!; + private string SearchTerm { get; set; } = string.Empty; + private bool IsReadOnlyMode { get; set; } + private string ReadonlyWorkflowsExcluded => Localizer["The read-only workflows will not be affected."]; + + private async Task> ServerReload(TableState state, CancellationToken cancellationToken) + { + var request = new ListWorkflowDefinitionsRequest + { + IsSystem = false, + Page = state.Page, + PageSize = state.PageSize, + SearchTerm = SearchTerm, + OrderBy = GetOrderBy(state.SortLabel), + OrderDirection = state.SortDirection == SortDirection.Descending + ? OrderDirection.Descending + : OrderDirection.Ascending + }; + + var latestWorkflowDefinitionsResponse = await WorkflowDefinitionService.ListAsync(request, VersionOptions.Latest); + IsReadOnlyMode = (latestWorkflowDefinitionsResponse?.Links?.Count(l => l.Rel == "bulk-publish") ?? 0) == 0; + var unpublishedWorkflowDefinitionIds = latestWorkflowDefinitionsResponse.Items.Where(x => !x.IsPublished).Select(x => x.DefinitionId).ToList(); + + var publishedWorkflowDefinitions = await WorkflowDefinitionService.ListAsync(new ListWorkflowDefinitionsRequest + { + DefinitionIds = unpublishedWorkflowDefinitionIds, + }, VersionOptions.Published); + + _totalCount = latestWorkflowDefinitionsResponse.TotalCount; + + var workflowDefinitionRows = latestWorkflowDefinitionsResponse.Items + .Select(definition => + { + var latestVersionNumber = definition.Version; + var isPublished = definition.IsPublished; + var publishedVersion = isPublished + ? definition + : publishedWorkflowDefinitions.Items.FirstOrDefault(x => x.DefinitionId == definition.DefinitionId); + var publishedVersionNumber = publishedVersion?.Version; + + return new WorkflowDefinitionRow( + definition.Id, + definition.DefinitionId, + latestVersionNumber, + publishedVersionNumber, + definition.Name, + definition.Description, + definition.IsPublished, + (definition?.Links?.Count(l => l.Rel == "publish") ?? 0) == 0); + }) + .ToList(); + + return new TableData + { + TotalItems = (int)_totalCount, + Items = workflowDefinitionRows + }; + } + + private OrderByWorkflowDefinition? GetOrderBy(string sortLabel) + { + return sortLabel switch + { + "Name" => OrderByWorkflowDefinition.Name, + "Version" => OrderByWorkflowDefinition.Version, + "Created" => OrderByWorkflowDefinition.Created, + _ => null + }; + } + + private async Task OnCreateWorkflowClicked() + { + var workflowName = await WorkflowDefinitionService.GenerateUniqueNameAsync(); + + var parameters = new DialogParameters + { + { x => x.WorkflowName, workflowName } + }; + + var options = new DialogOptions + { + CloseOnEscapeKey = true, + Position = DialogPosition.Center, + CloseButton = true, + FullWidth = true, + MaxWidth = MaxWidth.Small + }; + + var dialogInstance = await DialogService.ShowAsync(Localizer["New workflow"], parameters, options); + var dialogResult = await dialogInstance.Result; + + if (!dialogResult.Canceled) + { + var newWorkflowModel = (WorkflowMetadataModel)dialogResult.Data; + var result = await WorkflowDefinitionService.CreateNewDefinitionAsync(newWorkflowModel.Name!, newWorkflowModel.Description!); + + await result.OnSuccessAsync(definition => EditAsync(definition.DefinitionId)); + result.OnFailed(errors => Snackbar.Add(string.Join(Environment.NewLine, errors.Errors))); + } + } + + private async Task EditAsync(string definitionId) + { + await EditWorkflowDefinition.InvokeAsync(definitionId); + } + + private void Reload() + { + _table.ReloadServerData(); + } + + private async Task OnEditClicked(string definitionId) + { + await EditAsync(definitionId); + } + + private async Task OnRowClick(TableRowClickEventArgs e) + { + await EditAsync(e.Item.DefinitionId); + } + + private async Task OnRunWorkflowClicked(WorkflowDefinitionRow workflowDefinitionRow) + { + var request = new ExecuteWorkflowDefinitionRequest + { + VersionOptions = VersionOptions.Latest + }; + + var definitionId = workflowDefinitionRow!.DefinitionId; + var response = await WorkflowDefinitionService.ExecuteAsync(definitionId, request); + + if (response.CannotStart) + { + Snackbar.Add(Localizer["The workflow cannot be started"], Severity.Error); + return; + } + + Snackbar.Add(Localizer["Successfully started workflow"], Severity.Success); + } + + private async Task OnDeleteClicked(WorkflowDefinitionRow workflowDefinitionRow) + { + var result = await DialogService.ShowMessageBox(Localizer["Delete workflow?"], + Localizer["Are you sure you want to delete this workflow?"], yesText: Localizer["Delete"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + var definitionId = workflowDefinitionRow.DefinitionId; + await WorkflowDefinitionService.DeleteAsync(definitionId); + Reload(); + } + + private async Task OnCancelClicked(WorkflowDefinitionRow workflowDefinitionRow) + { + var result = await DialogService.ShowMessageBox(Localizer["Cancel running workflow instances?"], + Localizer["Are you sure you want to cancel all running workflow instances of this workflow definition?"], yesText: Localizer["Yes"], cancelText: Localizer["No"]); + + if (result != true) + return; + + var request = new BulkCancelWorkflowInstancesRequest + { + DefinitionVersionId = workflowDefinitionRow.Id + }; + await WorkflowInstanceService.BulkCancelAsync(request); + Reload(); + } + + private async Task OnDownloadClicked(WorkflowDefinitionRow workflowDefinitionRow) + { + var download = await WorkflowDefinitionService.ExportDefinitionAsync(workflowDefinitionRow.DefinitionId, VersionOptions.Latest); + var fileName = $"{workflowDefinitionRow.Name.Kebaberize()}.json"; + await Files.DownloadFileFromStreamAsync(fileName, download.Content); + } + + private async Task OnBulkDeleteClicked() + { + var result = await DialogService.ShowMessageBox( + Localizer["Delete selected workflows?"], + Localizer["Are you sure you want to delete the selected workflows?"] + (_selectedRows.Count(w => w.IsReadOnlyMode) > 0 ? ReadonlyWorkflowsExcluded : ""), yesText: Localizer["Delete"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + var workflowDefinitionIds = _selectedRows.Select(x => x.DefinitionId).ToList(); + await WorkflowDefinitionService.BulkDeleteAsync(workflowDefinitionIds); + _selectedRows.Clear(); + Reload(); + } + + private async Task OnBulkPublishClicked() + { + var result = await DialogService.ShowMessageBox(Localizer["Publish selected workflows?"], + Localizer["Are you sure you want to publish the selected workflows?"] + (_selectedRows.Count(w => w.IsReadOnlyMode) > 0 ? ReadonlyWorkflowsExcluded : ""), yesText: Localizer["Publish"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + var workflowDefinitionIds = _selectedRows.Select(x => x.DefinitionId).ToList(); + var response = await WorkflowDefinitionService.BulkPublishAsync(workflowDefinitionIds); + + if (response.Published.Count > 0) + { + var message = response.Published.Count == 1 + ? Localizer["One workflow is published"] + : Localizer["{0} workflows are published", response.Published.Count]; + Snackbar.Add(message, Severity.Success, options => { options.SnackbarVariant = Variant.Filled; }); + } + + if (response.AlreadyPublished.Count > 0) + { + var message = response.AlreadyPublished.Count == 1 + ? Localizer["One workflow is already published"] + : Localizer["{0} workflows are already published", response.AlreadyPublished.Count]; + Snackbar.Add(message, Severity.Info, options => { options.SnackbarVariant = Variant.Filled; }); + } + + if (response.UpdatedConsumers.Count > 0) + { + var message = response.UpdatedConsumers.Count == 1 + ? Localizer["One workflow consuming a published workflow has been updated"] + : Localizer["{0} workflows consuming published workflows have been updated", response.UpdatedConsumers.Count]; + Snackbar.Add(message, Severity.Info, options => + { + options.SnackbarVariant = Variant.Filled; + options.VisibleStateDuration = 3000; + }); + } + + if (response.NotFound.Count > 0) + { + var message = response.NotFound.Count == 1 + ? Localizer["One workflow is not found"] + : Localizer["{0} workflows are not found", response.NotFound.Count]; + Snackbar.Add(message, Severity.Warning, options => { options.SnackbarVariant = Variant.Filled; }); + } + _selectedRows.Clear(); + Reload(); + } + + private async Task OnBulkRetractClicked() + { + var result = await DialogService.ShowMessageBox(Localizer["Unpublish selected workflows?"], + Localizer["Are you sure you want to unpublish the selected workflows?"] + (_selectedRows.Count(w => w.IsReadOnlyMode) > 0 ? ReadonlyWorkflowsExcluded : ""), yesText: Localizer["Unpublish"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + var workflowDefinitionIds = _selectedRows.Select(x => x.DefinitionId).ToList(); + var response = await WorkflowDefinitionService.BulkRetractAsync(workflowDefinitionIds); + + if (response.Retracted.Count > 0) + { + var message = response.Retracted.Count == 1 + ? Localizer["One workflow is unpublished"] + : Localizer["{0} workflows are unpublished", response.Retracted.Count]; + Snackbar.Add(message, Severity.Success, options => { options.SnackbarVariant = Variant.Filled; }); + } + + if (response.AlreadyRetracted.Count > 0) + { + var message = response.AlreadyRetracted.Count == 1 + ? Localizer["One workflow is already unpublished"] + : Localizer["{0} workflows are already unpublished", response.AlreadyRetracted.Count]; + Snackbar.Add(message, Severity.Info, options => { options.SnackbarVariant = Variant.Filled; }); + } + + if (response.NotFound.Count > 0) + { + var message = response.NotFound.Count == 1 + ? Localizer["One workflow is not found"] + : Localizer["{0} workflows are not found", response.NotFound.Count]; + Snackbar.Add(message, Severity.Warning, options => { options.SnackbarVariant = Variant.Filled; }); + } + _selectedRows.Clear(); + Reload(); + } + + private async Task OnBulkExportClicked() + { + var workflowVersionIds = _selectedRows.Select(x => x.Id).ToList(); + var download = await WorkflowDefinitionService.BulkExportDefinitionsAsync(workflowVersionIds); + var fileName = download.FileName; + await Files.DownloadFileFromStreamAsync(fileName, download.Content); + _selectedRows.Clear(); + Reload(); + } + + private Task OnImportClicked() + { + return DomAccessor.ClickElementAsync("#workflow-file-upload-button-wrapper input[type=file]"); + } + + private async Task OnFilesSelected(IReadOnlyList files) + { + var results = (await WorkflowDefinitionImporter.ImportFilesAsync(files)).ToList(); + var successfulResultCount = results.Count(x => x.IsSuccess); + var failedResultCount = results.Count(x => !x.IsSuccess); + var successfulWorkflowsTerm = successfulResultCount == 1 ? "workflow" : "workflows"; + var failedWorkflowsTerm = failedResultCount == 1 ? Localizer["workflow"] : Localizer["workflows"]; + var message = results.Count == 0 ? Localizer["No workflows found to import."] : + successfulResultCount > 0 && failedResultCount == 0 ? Localizer["{0} {1} imported successfully.", successfulResultCount, successfulWorkflowsTerm] : + successfulResultCount == 0 && failedResultCount > 0 ? Localizer["Failed to import {0} {1}.", failedResultCount, failedWorkflowsTerm] : Localizer["{0} {1} imported successfully.", successfulResultCount, successfulWorkflowsTerm] + " " + Localizer["Failed to import {0} {1}.", failedResultCount, failedWorkflowsTerm]; + var severity = results.Count == 0 ? Severity.Info : successfulResultCount > 0 && failedResultCount > 0 ? Severity.Warning : failedResultCount == 0 ? Severity.Success : Severity.Error; + Snackbar.Add(message, severity, options => + { + options.SnackbarVariant = Variant.Filled; + options.CloseAfterNavigation = failedResultCount > 0; + options.VisibleStateDuration = failedResultCount > 0 ? 10000 : 3000; + }); + Reload(); + } + + private void OnSearchTermChanged(string text) + { + if (SearchTerm != text) + { + SearchTerm = text; + Reload(); + } + } + + private async Task OnPublishClicked(string definitionId) + { + var response = await WorkflowDefinitionService.PublishAsync(definitionId); + if (response.AlreadyPublished) + { + Snackbar.Add(Localizer["Workflow was already published"], Severity.Info, options => { options.SnackbarVariant = Variant.Filled; }); + } + else + { + Snackbar.Add(Localizer["Workflow published"], Severity.Success, options => { options.SnackbarVariant = Variant.Filled; }); + } + + if (response.ConsumingWorkflowCount > 0) + { + var message = response.ConsumingWorkflowCount == 1 + ? Localizer["One workflow consuming a published workflow has been updated"] + : Localizer["{0} workflows consuming published workflows have been updated", response.ConsumingWorkflowCount]; + Snackbar.Add(message, Severity.Info, options => + { + options.SnackbarVariant = Variant.Filled; + options.VisibleStateDuration = 3000; + }); + } + + Reload(); + } + + private async Task OnRetractClicked(string definitionId) + { + await WorkflowDefinitionService.RetractAsync(definitionId); + Snackbar.Add(Localizer["Workflow retracted"], Severity.Success, options => { options.SnackbarVariant = Variant.Filled; }); + Reload(); + } + + private record WorkflowDefinitionRow( + string Id, + string DefinitionId, + int LatestVersion, + int? PublishedVersion, + string? Name, + string? Description, + bool IsPublished, + bool IsReadOnlyMode); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Components/BulkCancelDialog.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Components/BulkCancelDialog.razor new file mode 100644 index 0000000..841302a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Components/BulkCancelDialog.razor @@ -0,0 +1,15 @@ + + + @MudDialog.Title + + + + Are you sure you want to cancel the selected workflow instances? + + + + + No + Yes + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Components/BulkCancelDialog.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Components/BulkCancelDialog.razor.cs new file mode 100644 index 0000000..3f39bd7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Components/BulkCancelDialog.razor.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceList.Components; + +public partial class BulkCancelDialog : ComponentBase +{ + private bool ApplyToAllMatches { get; set; } + [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!; + + private void Submit() => MudDialog.Close(DialogResult.Ok(ApplyToAllMatches)); + + private void Cancel() => MudDialog.Close(DialogResult.Cancel()); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Models/TimestampFilter.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Models/TimestampFilter.cs new file mode 100644 index 0000000..e79fdcc --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Models/TimestampFilter.cs @@ -0,0 +1,30 @@ +using Elsa.Api.Client.Shared.Enums; +using JetBrains.Annotations; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceList.Models; + +/// +/// Represents a timestamp filter used for filtering data based on a specified timestamp column and operator. +/// +public class TimestampFilterModel +{ + /// + /// Gets or sets the column to filter by. + /// + public string Column { get; set; } = default!; + + /// + /// Gets or sets the operator to use for filtering. + /// + public TimestampFilterOperator Operator { get; set; } + + /// + /// Gets or sets the date to filter by. + /// + public string Date { get; set; } + + /// + /// Gets or sets the time to filter by. + /// + public string? Time { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Models/WorkflowInstanceRow.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Models/WorkflowInstanceRow.cs new file mode 100644 index 0000000..f2215ba --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/Models/WorkflowInstanceRow.cs @@ -0,0 +1,18 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Enums; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceList.Models; + +internal record WorkflowInstanceRow( + string WorkflowInstanceId, + string? CorrelationId, + string WorkflowDefinitionName, + int Version, + string? Name, + WorkflowStatus Status, + WorkflowSubStatus SubStatus, + int IncidentCount, + DateTimeOffset CreatedAt, + DateTimeOffset? UpdatedAt, + DateTimeOffset? FinishedAt +); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/WorkflowInstanceList.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/WorkflowInstanceList.razor new file mode 100644 index 0000000..cb9e638 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/WorkflowInstanceList.razor @@ -0,0 +1,302 @@ +@inherits StudioComponentBase + +@using System.Globalization +@using Elsa.Api.Client.Resources.WorkflowDefinitions.Models +@using Elsa.Api.Client.Resources.WorkflowInstances.Enums +@using Elsa.Api.Client.Resources.WorkflowInstances.Models +@using Elsa.Api.Client.Shared.Enums +@using Elsa.Studio.Workflows.Components.WorkflowInstanceList.Models +@using Elsa.Studio.Workflows.Services +@using Microsoft.Extensions.Localization +@inject ILocalizer Localizer + +@using AlignItems = MudBlazor.AlignItems +@using Variant = MudBlazor.Variant + +@Localizer["Workflow instances"] + + + + +
+ +
+ + + + + + @Localizer["Delete"] + @Localizer["Cancel"] + @* @Localizer["Retry"] *@ + @* Export *@ + + @Localizer["Import"] + + + + + + - + @Localizer["Yes"] + @Localizer["No"] + + + + + + + + + @Localizer["Running"] + @Localizer["Finished"] + + + + @Localizer["Executing"] + @Localizer["Suspended"] + @Localizer["Finished"] + @Localizer["Faulted"] + @Localizer["Cancelled"] + + + + + @Localizer["Date Filters"] + + + + + + @foreach (var timestampFilter in TimestampFilters) + { + + + + + + + + } + +
+ + + + @Localizer["Created"] + @Localizer["Updated"] + @Localizer["Finished"] + + + + @Localizer["Is"] + @Localizer["Is Not"] + @Localizer["Is After"] + @Localizer["Is on or After"] + @Localizer["Is Before"] + @Localizer["Is on or Before"] + + + + + + @* *@ +
+ + @Localizer["Add"] + @Localizer["Clear"] + + @Localizer["Apply"] + @Localizer["Close"] + +
+
+ + @Localizer["ID"] + @Localizer["Correlation ID"] + @Localizer["Workflows"] + @Localizer["Version"] + + @Localizer["Name"] + + + @Localizer["Status"] + + + @Localizer["Incidents"] + + + @Localizer["Created"] + + + @Localizer["Updated"] + + + @Localizer["Finished"] + + + + + @context.WorkflowInstanceId + + +
+ @context.CorrelationId +
+
+
+ + +
+ @context.WorkflowDefinitionName +
+
+
+ @context.Version + + +
+ @context.Name +
+
+
+ + + @Localizer[context.SubStatus.ToString()] + + + + + + + + + + + @Localizer["View"] + @Localizer["Delete"] + @Localizer["Cancel"] + @* Disabled until we fix an issue with Workflow Instance Exports. *@ + @* *@ + @* Export *@ + + +
+ + @Localizer["No workflow instances found"] + + + @Localizer["Loading"]... + + + + +
+
+ + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/WorkflowInstanceList.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/WorkflowInstanceList.razor.cs new file mode 100644 index 0000000..24831d0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceList/WorkflowInstanceList.razor.cs @@ -0,0 +1,438 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.Alterations.Contracts; +using Elsa.Api.Client.Resources.Alterations.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Enums; +using Elsa.Api.Client.Resources.WorkflowInstances.Requests; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Contracts; +using Elsa.Studio.DomInterop.Contracts; +using Elsa.Studio.Workflows.Components.WorkflowInstanceList.Components; +using Elsa.Studio.Workflows.Components.WorkflowInstanceList.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using MudBlazor; +using Refit; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Microsoft.Extensions.Logging; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceList; + +/// Represents the workflow instances list page. +public partial class WorkflowInstanceList : IAsyncDisposable +{ + private MudTable _table = null!; + private HashSet _selectedRows = new(); + private int _totalCount; + private Timer? _elapsedTimer; + + /// + /// An event that is invoked when a workflow definition is edited. + /// + [Parameter] public EventCallback ViewWorkflowInstance { get; set; } + + [Inject] private IDialogService DialogService { get; set; } = null!; + [Inject] private ISnackbar Snackbar { get; set; } = null!; + [Inject] private IWorkflowInstanceService WorkflowInstanceService { get; set; } = null!; + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = null!; + [Inject] private IBackendApiClientProvider BackendApiClientProvider { get; set; } = null!; + [Inject] private IFiles Files { get; set; } = null!; + [Inject] private IDomAccessor DomAccessor { get; set; } = null!; + [Inject] private ILogger Logger { get; set; } = null!; + + private ICollection WorkflowDefinitions { get; set; } = new List(); + private ICollection SelectedWorkflowDefinitions { get; set; } = new List(); + + private string SearchTerm { get; set; } = string.Empty; + private bool? HasIncidents { get; set; } + private bool IsDateRangePopoverOpen { get; set; } + + /// The selected statuses to filter by. + private ICollection SelectedStatuses { get; set; } = new List(); + + /// The selected sub-statuses to filter by. + private ICollection SelectedSubStatuses { get; set; } = new List(); + + // The selected timestamp filters to filter by. + private ICollection TimestampFilters { get; set; } = new List(); + + + /// + protected override async Task OnInitializedAsync() + { + await LoadWorkflowDefinitionsAsync(); + + // Disable auto refresh until we implement a way to maintain the selected state, pagination etc. + //StartElapsedTimer(); + } + + private async Task LoadWorkflowDefinitionsAsync() + { + var workflowDefinitionsResponse = await WorkflowDefinitionService.ListAsync(new(), VersionOptions.LatestOrPublished); + var workflowDefinitions = workflowDefinitionsResponse.Items; + + // Filter the definitions to ensure only the one with the highest version for each DefinitionId remains + var filteredWorkflowDefinitions = workflowDefinitions + .GroupBy(definition => definition.DefinitionId) // Group by DefinitionId + .Select(group => group.OrderByDescending(definition => definition.Version).First()) // Get the highest version in each group + .ToList(); + + WorkflowDefinitions = filteredWorkflowDefinitions; + } + + private async Task> LoadData(TableState state, CancellationToken cancellationToken) + { + var request = new ListWorkflowInstancesRequest + { + Page = state.Page, + PageSize = state.PageSize, + DefinitionIds = SelectedWorkflowDefinitions.Select(x => x.DefinitionId).ToList(), + Statuses = SelectedStatuses, + SubStatuses = SelectedSubStatuses, + SearchTerm = SearchTerm, + HasIncidents = HasIncidents, + IsSystem = false, + OrderBy = GetOrderBy(state.SortLabel), + OrderDirection = state.SortDirection == SortDirection.Descending ? OrderDirection.Descending : OrderDirection.Ascending, + TimestampFilters = TimestampFilters.Select(Map).Where(x => x.Timestamp.Date > DateTime.MinValue && !string.IsNullOrWhiteSpace(x.Column)).ToList() + }; + + try + { + var workflowInstancesResponse = await WorkflowInstanceService.ListAsync(request, cancellationToken); + var definitionVersionIds = workflowInstancesResponse.Items.Select(x => x.DefinitionVersionId).Distinct().ToList(); + + var workflowDefinitionVersionsResponse = await WorkflowDefinitionService.ListAsync(new() + { + Ids = definitionVersionIds, + }, cancellationToken: cancellationToken); + + var workflowDefinitionVersionsLookup = workflowDefinitionVersionsResponse.Items.ToDictionary(x => x.Id); + + // Select any workflow instances for which no corresponding workflow definition version was found. + // This can happen when a workflow definition is deleted. + var missingWorkflowDefinitionVersionIds = definitionVersionIds.Except(workflowDefinitionVersionsLookup.Keys).ToList(); + var filteredWorkflowInstances = workflowInstancesResponse.Items.Where(x => !missingWorkflowDefinitionVersionIds.Contains(x.DefinitionVersionId)); + + var rows = filteredWorkflowInstances.Select(x => new WorkflowInstanceRow( + x.Id, + x.CorrelationId, + workflowDefinitionVersionsLookup[x.DefinitionVersionId]?.Name ?? "", + x.Version, + x.Name, + x.Status, + x.SubStatus, + x.IncidentCount, + x.CreatedAt, + x.UpdatedAt, + x.FinishedAt)); + + _totalCount = (int)workflowInstancesResponse.TotalCount; + return new() { TotalItems = _totalCount, Items = rows }; + } + catch (TaskCanceledException) + { + Logger.LogWarning("Failed to list workflow instances due to a cancellation."); + _totalCount = 0; + return new() { TotalItems = 0, Items = Array.Empty() }; + } + catch (ApiException ex) when (ex.InnerException is TaskCanceledException) + { + Logger.LogWarning("Failed to list workflow instances due to a cancellation."); + _totalCount = 0; + return new() { TotalItems = 0, Items = Array.Empty() }; + } + } + + private async Task> TryListWorkflowDefinitionsAsync(ListWorkflowInstancesRequest request, CancellationToken cancellationToken) + { + try + { + return await WorkflowInstanceService.ListAsync(request, cancellationToken); + } + catch (ApiException ex) when (ex.InnerException is TaskCanceledException) + { + Logger.LogWarning("Failed to list workflow instances due to a timeout."); + return new() + { + Items = [] + }; + } + } + + private TimestampFilter Map(TimestampFilterModel source) + { + var date = !string.IsNullOrWhiteSpace(source.Date) ? DateTime.Parse(source.Date) : DateTime.MinValue; + var time = !string.IsNullOrWhiteSpace(source.Time) ? TimeSpan.Parse(source.Time) : TimeSpan.Zero; + var dateTime = date.Add(time); + var timestamp = dateTime == DateTime.MinValue ? DateTimeOffset.MinValue : new(dateTime); + + return new() + { + Column = source.Column, + Operator = source.Operator, + Timestamp = timestamp + }; + } + + private OrderByWorkflowInstance? GetOrderBy(string sortLabel) + { + return sortLabel switch + { + "Name" => OrderByWorkflowInstance.Name, + "Finished" => OrderByWorkflowInstance.Finished, + "Created" => OrderByWorkflowInstance.Created, + "LastExecuted" => OrderByWorkflowInstance.LastExecuted, + _ => null + }; + } + + private async Task ViewAsync(string instanceId) + { + await ViewWorkflowInstance.InvokeAsync(instanceId); + } + + private void Reload() => _table.ReloadServerData(); + + private bool FilterWorkflowDefinitions(WorkflowDefinitionSummary workflowDefinition, string term) + { + var trimmedTerm = term.Trim(); + + if (string.IsNullOrEmpty(term)) + return true; + + var sources = new[] + { + (string?)workflowDefinition.Name + }; + + return sources.Any(x => x?.Contains(trimmedTerm, StringComparison.OrdinalIgnoreCase) == true); + } + + private Color GetSubStatusColor(WorkflowSubStatus subStatus) + { + return subStatus switch + { + WorkflowSubStatus.Pending => Color.Tertiary, + WorkflowSubStatus.Suspended => Color.Warning, + WorkflowSubStatus.Finished => Color.Success, + WorkflowSubStatus.Faulted => Color.Error, + WorkflowSubStatus.Cancelled => Color.Tertiary, + WorkflowSubStatus.Executing => Color.Primary, + _ => Color.Default, + }; + } + + private string? GetWorkflowDefinitionDisplayText(WorkflowDefinitionSummary? definition) + { + return definition?.Name; + } + + private void ToggleDateRangePopover() + { + IsDateRangePopoverOpen = !IsDateRangePopoverOpen; + } + + private void OnViewClicked(string instanceId) => _ = ViewAsync(instanceId); + private void OnRowClick(TableRowClickEventArgs e) => _ = ViewAsync(e.Item!.WorkflowInstanceId); + + private async Task OnDeleteClicked(WorkflowInstanceRow row) + { + var result = await DialogService.ShowMessageBox(Localizer["Delete workflow instance?"], Localizer["Are you sure you want to delete this workflow instance?"], yesText: Localizer["Delete"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + var instanceId = row.WorkflowInstanceId; + await WorkflowInstanceService.DeleteAsync(instanceId); + Reload(); + } + + private async Task OnCancelClicked(WorkflowInstanceRow row) + { + var result = await DialogService.ShowMessageBox(Localizer["Cancel workflow instance?"], Localizer["Are you sure you want to cancel this workflow instance?"], yesText: Localizer["Yes"], cancelText: Localizer["No"]); + + if (result != true) + return; + + var instanceId = row.WorkflowInstanceId; + await WorkflowInstanceService.CancelAsync(instanceId); + Reload(); + } + + private async Task OnDownloadClicked(WorkflowInstanceRow workflowInstanceRow) + { + var download = await WorkflowInstanceService.ExportAsync(workflowInstanceRow.WorkflowInstanceId); + var fileName = $"{workflowInstanceRow.Name?.Kebaberize() ?? workflowInstanceRow.WorkflowInstanceId}.json"; + await Files.DownloadFileFromStreamAsync(fileName, download.Content); + } + + private async Task OnBulkDeleteClicked() + { + var result = await DialogService.ShowMessageBox(Localizer["Delete selected workflow instances?"], Localizer["Are you sure you want to delete the selected workflow instances?"], yesText: Localizer["Delete"], cancelText: Localizer["Cancel"]); + + if (result != true) + return; + + var workflowInstanceIds = _selectedRows.Select(x => x.WorkflowInstanceId).ToList(); + await WorkflowInstanceService.BulkDeleteAsync(workflowInstanceIds); + _selectedRows.Clear(); + Reload(); + } + + private async Task OnBulkCancelClicked() + { + var reference = await DialogService.ShowAsync(Localizer["Cancel selected workflow instances?"]); + var dialogResult = await reference.Result; + + if (dialogResult == null || dialogResult.Canceled) + return; + + var applyToAllMatches = (bool)(dialogResult.Data ?? false); + + if (applyToAllMatches) + { + var cancel = new JsonObject + { + ["type"] = "Cancel" + }; + + var plan = new AlterationPlanParams + { + Alterations = [cancel], + Filter = new() + { + EmptyFilterSelectsAll = true, + HasIncidents = HasIncidents, + IsSystem = false, + SearchTerm = SearchTerm, + Statuses = SelectedStatuses.Any() ? SelectedStatuses : null, + SubStatuses = SelectedSubStatuses.Any() ? SelectedSubStatuses : null, + TimestampFilters = TimestampFilters.Any() ? TimestampFilters.Select(Map).Where(x => x.Timestamp.Date > DateTime.MinValue && !string.IsNullOrWhiteSpace(x.Column)).ToList() : null, + DefinitionIds = SelectedWorkflowDefinitions.Any() ? SelectedWorkflowDefinitions.Select(x => x.DefinitionId).ToList() : null + } + }; + + var alterationsApi = await BackendApiClientProvider.GetApiAsync(); + await alterationsApi.Submit(plan); + Snackbar.Add("Workflow instances are being cancelled.", Severity.Info, options => + { + options.SnackbarVariant = Variant.Filled; + options.ShowTransitionDuration = 2000; + }); + } + else + { + var workflowInstanceIds = _selectedRows.Select(x => x.WorkflowInstanceId).ToList(); + var request = new BulkCancelWorkflowInstancesRequest + { + Ids = workflowInstanceIds + }; + await WorkflowInstanceService.BulkCancelAsync(request); + } + + Reload(); + } + + private Task OnImportClicked() + { + return DomAccessor.ClickElementAsync("#instance-file-upload-button-wrapper input[type=file]"); + } + + private async Task OnFilesSelected(IReadOnlyList files) + { + var maxAllowedSize = 1024 * 1024 * 10; // 10 MB + var streamParts = files.Select(x => new StreamPart(x.OpenReadStream(maxAllowedSize), x.Name, x.ContentType)).ToList(); + var count = await WorkflowInstanceService.BulkImportAsync(streamParts); + var message = count == 1 ? Localizer["Successfully imported one instance"] : Localizer["Successfully imported {0} instances", count]; + Snackbar.Add(message, Severity.Success, options => { options.SnackbarVariant = Variant.Filled; }); + Reload(); + } + + private async Task OnBulkExportClicked() + { + var workflowInstanceIds = _selectedRows.Select(x => x.WorkflowInstanceId).ToList(); + var download = await WorkflowInstanceService.BulkExportAsync(workflowInstanceIds); + var fileName = download.FileName; + await Files.DownloadFileFromStreamAsync(fileName, download.Content); + } + + private async Task OnSelectedWorkflowDefinitionsChanged(IEnumerable values) + { + SelectedWorkflowDefinitions = values.ToList(); + await _table.ReloadServerData(); + } + + private async Task OnSelectedStatusesChanged(IEnumerable values) + { + SelectedStatuses = values.ToList(); + await _table.ReloadServerData(); + } + + private async Task OnSelectedSubStatusesChanged(IEnumerable values) + { + SelectedSubStatuses = values.ToList(); + await _table.ReloadServerData(); + } + + private async Task OnSearchTermChanged(string text) + { + if (text != SearchTerm) + { + SearchTerm = text; + await _table.ReloadServerData(); + } + } + + private async Task OnHasIncidentsChanged(bool? value) + { + HasIncidents = value; + await _table.ReloadServerData(); + } + + private void OnAddTimestampFilterClicked() + { + TimestampFilters.Add(new()); + StateHasChanged(); + } + + private void OnRemoveTimestampFilterClicked(TimestampFilterModel filter) + { + TimestampFilters.Remove(filter); + StateHasChanged(); + } + + private void OnClearTimestampFiltersClicked() + { + TimestampFilters.Clear(); + StateHasChanged(); + } + + private async Task OnApplyTimestampFiltersClicked() + { + await _table.ReloadServerData(); + ToggleDateRangePopover(); + } + + private void StartElapsedTimer() + { + _elapsedTimer ??= new(_ => InvokeAsync(async () => await _table.ReloadServerData()), null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); + } + + private void StopElapsedTimer() + { + if (_elapsedTimer != null) + { + _elapsedTimer.Dispose(); + _elapsedTimer = null; + } + } + + ValueTask IAsyncDisposable.DisposeAsync() + { + StopElapsedTimer(); + return ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityDetailsTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityDetailsTab.razor new file mode 100644 index 0000000..9a5739b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityDetailsTab.razor @@ -0,0 +1,51 @@ +@inherits StudioComponentBase +@inject ILocalizer Localizer + + + +
+ @Localizer["Activity"] + +
+ + @if (ActivityData.Any()) + { +
+ @Localizer["State"] + +
+ } + + @if (OutcomesData.Any()) + { +
+ @Localizer["Outcomes"] + +
+ } + + @if (OutputData.Any()) + { +
+ @Localizer["Output"] + +
+ } + + @if (ExceptionData.Any()) + { +
+ @Localizer["Fault"] + +
+ } + + @if (ResilienceStrategyData.Any()) + { +
+ @Localizer["Resilience Strategy"] + +
+ } +
+
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityDetailsTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityDetailsTab.razor.cs new file mode 100644 index 0000000..74499f4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityDetailsTab.razor.cs @@ -0,0 +1,153 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityExecutions.Models; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +/// Displays the details of an activity. +public partial class ActivityDetailsTab +{ + /// The height of the visible pane. + [Parameter] public int VisiblePaneHeight { get; set; } + + /// The activity to display details for. + [Parameter] public JsonObject Activity { get; set; } = null!; + + /// The latest activity execution record. Used for displaying the last state of the activity. + [Parameter] public ActivityExecutionRecord? LastActivityExecution { get; set; } + + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = null!; + + private DataPanelModel ActivityInfo { get; set; } = new(); + private DataPanelModel ActivityData { get; set; } = new(); + private DataPanelModel OutcomesData { get; set; } = new(); + private DataPanelModel OutputData { get; set; } = new(); + private DataPanelModel ExceptionData { get; set; } = new(); + private DataPanelModel ResilienceStrategyData { get; set; } = new(); + + /// Refreshes the component. + public void Refresh() + { + CreateDataModels(); + StateHasChanged(); + } + + /// + protected override void OnParametersSet() + { + } + + /// + protected override void OnInitialized() + { + CreateDataModels(); + } + + private void CreateDataModels() + { + var activity = Activity; + var activityDescriptor = ActivityRegistry.Find(activity.GetTypeName(), activity.GetVersion())!; + var activityId = activity.GetId(); + var activityName = activity.GetName(); + var activityType = activity.GetTypeName(); + var execution = LastActivityExecution; + var activityVersion = activity.GetVersion(); + var exception = execution?.Exception; + var workflowDefinitionId = activity.GetIsWorkflowDefinitionActivity() ? activity.GetWorkflowDefinitionId() : null; + var props = execution?.Properties; + var resilienceStrategy = props != null && props.TryGetValue("ResilienceStrategy", out var resilienceStrategyModel) && resilienceStrategyModel is JsonElement resilienceStrategyElement ? resilienceStrategyElement : default(JsonElement?); + + var activityInfo = new DataPanelModel + { + new DataPanelItem("ID", activityId), + new DataPanelItem(Localizer["Name"], activityName), + new DataPanelItem(Localizer["Type"], activityType, + string.IsNullOrWhiteSpace(workflowDefinitionId) + ? null + : $"/workflows/definitions/{workflowDefinitionId}/edit"), + new DataPanelItem(Localizer["Version"], activityVersion.ToString()) + }; + + var outcomesData = new DataPanelModel(); + var outputData = new DataPanelModel(); + + if (execution != null) + { + activityInfo.Add(Localizer["Status"], execution.Status.ToString()); + activityInfo.Add(Localizer["Instance ID"], execution.Id); + + if (execution.Payload != null) + if (execution.Payload.TryGetValue("Outcomes", out var outcomes)) + outcomesData.Add("Outcomes", outcomes.ToString()); + + var outputDescriptors = activityDescriptor.Outputs; + var outputs = execution.Outputs; + + foreach (var outputDescriptor in outputDescriptors) + { + var outputValue = outputs != null + ? outputs.TryGetValue(outputDescriptor.Name, out var value) ? value : null + : null; + outputData.Add(outputDescriptor.Name, outputValue?.ToString()); + } + } + else + { + activityInfo.Add("Status", Localizer["Not executed"]); + } + + var exceptionData = new DataPanelModel(); + + if (exception != null) + { + exceptionData.Add("Message", exception.Message); + exceptionData.Add("InnerException", exception.InnerException != null + ? exception.InnerException.Type + ": " + exception.InnerException.Message + : null); + exceptionData.Add("StackTrace", exception.StackTrace); + } + + var activityStateData = new DataPanelModel(); + var activityState = execution?.ActivityState; + + if (activityState != null) + { + foreach (var inputDescriptor in activityDescriptor.Inputs) + { + var inputValue = activityState.TryGetValue(inputDescriptor.Name, out var value) ? value : null; + activityStateData.Add(inputDescriptor.Name, inputValue?.ToString()); + } + } + + var resilienceStrategyData = new DataPanelModel(); + + if (resilienceStrategy != null) + { + var resilienceStrategyJson = JsonSerializer.Serialize(resilienceStrategy.Value, JsonSerializerOptions.Default); + var dict = JsonSerializer.Deserialize>(resilienceStrategyJson)!; + var type = "Unknown"; + + if (dict.ContainsKey("$type")) + { + type = dict["$type"].ToString(); + dict.Remove("$type"); + } + + var panelItems = dict.Select(x => new DataPanelItem(x.Key.Pascalize(), x.Value.ToString())); + resilienceStrategyData.Add("Type", type); + resilienceStrategyData.AddRange(panelItems); + } + + ActivityInfo = activityInfo; + ActivityData = activityStateData; + OutcomesData = outcomesData; + OutputData = outputData; + ExceptionData = exceptionData; + ResilienceStrategyData = resilienceStrategyData; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityExecutionsTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityExecutionsTab.razor new file mode 100644 index 0000000..a0f1626 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityExecutionsTab.razor @@ -0,0 +1,68 @@ +@inherits StudioComponentBase +@inject ILocalizer Localizer + + + + + + # + @Localizer["Started"] + @Localizer["Completed"] + @Localizer["Duration"] + @Localizer["Status"] + @Localizer["Has Retries"] + @Localizer["Activity Instance ID"] + + + @{ + var record = context.ActivityExecutionSummary; + } + @context.Number + + + @(record.CompletedAt != null ? (record.CompletedAt - record.StartedAt).Value.ToString("g") : "") + @record.Status + @(context.HasRetries ? Localizer["Yes"] : string.Empty) + @record.Id + + + + + + + @if (SelectedItem != null) + { +
+
+ @Localizer["State"] + +
+
+ @Localizer["Outcomes"] + +
+
+ @Localizer["Output"] + +
+ @if (Retries.TotalCount > 0) + { +
+ @Localizer["Retry Attempts"] + +
+ } +
+ } +
+
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityExecutionsTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityExecutionsTab.razor.cs new file mode 100644 index 0000000..87b98d7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ActivityExecutionsTab.razor.cs @@ -0,0 +1,138 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.ActivityExecutions.Models; +using Elsa.Api.Client.Resources.Resilience.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Extensions; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +/// Displays the details of an activity. +public partial class ActivityExecutionsTab : IAsyncDisposable +{ + /// Represents a row in the table of activity executions. + /// The number of executions. + /// The activity execution summary. + public record ActivityExecutionRecordTableRow(int Number, ActivityExecutionRecordSummary ActivityExecutionSummary) + { + /// Indicates whether the activity execution record has recorded retries. + public bool HasRetries => ActivityExecutionSummary.Metadata != null && ActivityExecutionSummary.Metadata.TryGetValue("HasRetryAttempts", out var retryAttempts) && retryAttempts is JsonElement { ValueKind: JsonValueKind.True }; + } + + /// The height of the visible pane. + [Parameter] public int VisiblePaneHeight { get; set; } + + /// The activity to display executions for. + [Parameter] public JsonObject Activity { get; set; } = null!; + + /// The activity execution record summaries. + [Parameter] public ICollection ActivityExecutionSummaries { get; set; } = new List(); + + [Inject] private IActivityExecutionService ActivityExecutionService { get; set; } = null!; + + private IEnumerable Items => ActivityExecutionSummaries.Select((x, i) => new ActivityExecutionRecordTableRow(i + 1, x)); + private ActivityExecutionRecord? SelectedItem { get; set; } + private PagedListResponse Retries { get; set; } = new(); + private DataPanelModel SelectedActivityState { get; set; } = new(); + private DataPanelModel SelectedOutcomesData { get; set; } = new(); + private DataPanelModel SelectedOutputData { get; set; } = new(); + private Timer? _refreshTimer; + + /// Refreshes the component. + public async Task RefreshAsync() + { + await StopRefreshTimerAsync(); + SelectedItem = null; + SelectedActivityState = new(); + SelectedOutcomesData = new(); + SelectedOutputData = new(); + } + + private void CreateSelectedItemDataModels(ActivityExecutionRecord? record) + { + if (record == null) + { + SelectedActivityState = new(); + SelectedOutcomesData = new(); + SelectedOutputData = new(); + return; + } + + var activityState = record.ActivityState? + .Where(x => !x.Key.StartsWith("_")) + .Select(x => new DataPanelItem(x.Key, x.Value?.ToString())) + .ToDataPanelModel(); + + var outcomesData = record.Payload?.TryGetValue("Outcomes", out var outcomesValue) == true + ? new DataPanelModel { new DataPanelItem("Outcomes", outcomesValue!.ToString()!) } + : null; + + var outputData = new DataPanelModel(); + + if (record.Outputs != null) + foreach (var (key, value) in record.Outputs) + outputData.Add(key, value?.ToString()); + + SelectedActivityState = activityState ?? new(); + SelectedOutcomesData = outcomesData ?? new(); + SelectedOutputData = outputData; + } + + private async Task RefreshSelectedItemAsync(string id) + { + SelectedItem = await ActivityExecutionService.GetAsync(id); + var retryAttempts = await ActivityExecutionService.GetRetriesAsync(id); + CreateSelectedItemDataModels(SelectedItem); + Retries = retryAttempts; + await InvokeAsync(StateHasChanged); + } + + private async Task OnActivityExecutionClicked(TableRowClickEventArgs arg) + { + await StopRefreshTimerAsync(); + var id = arg.Item?.ActivityExecutionSummary.Id; + + if (id == null) + return; + + await RefreshSelectedItemAsync(id); + + if (SelectedItem == null) + return; + + if (SelectedItem.IsFused()) + return; + + RefreshSelectedItemPeriodically(id); + } + + private void RefreshSelectedItemPeriodically(string id) + { + async void Callback(object? _) + { + await RefreshSelectedItemAsync(id); + + if (SelectedItem == null || SelectedItem.IsFused()) + await StopRefreshTimerAsync(); + } + + _refreshTimer = new Timer(Callback, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + } + + private async Task StopRefreshTimerAsync() + { + if (_refreshTimer == null) return; + await _refreshTimer.DisposeAsync(); + _refreshTimer = null; + } + + async ValueTask IAsyncDisposable.DisposeAsync() + { + if (_refreshTimer != null) await _refreshTimer.DisposeAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ElapsedTime.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ElapsedTime.razor new file mode 100644 index 0000000..739c5b8 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ElapsedTime.razor @@ -0,0 +1 @@ +@Elapsed.ToString(@"hh\:mm\:ss") \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ElapsedTime.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ElapsedTime.razor.cs new file mode 100644 index 0000000..1217682 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/ElapsedTime.razor.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +/// +/// Represents the elapsed time between a start and end point. +/// +public partial class ElapsedTime +{ + /// + /// Gets or sets the start time for the property. + /// + /// The start time. + /// + /// The start time represents the point in time from which the property should be considered. + /// The default value is set to the current UTC time. + /// + [Parameter] + public DateTimeOffset StartTime { get; set; } = DateTimeOffset.UtcNow; + + /// + /// Gets or sets the end time. + /// The end time represents the date and time when the event or activity ends. + /// + /// + /// The default value is set to the current Coordinated Universal Time (UTC) using . + /// + /// + /// The end time as a value. + /// + [Parameter] + public DateTimeOffset EndTime { get; set; } = DateTimeOffset.UtcNow; + + private TimeSpan Elapsed => EndTime < StartTime ? TimeSpan.Zero : EndTime - StartTime; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/Journal.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/Journal.razor new file mode 100644 index 0000000..84e7502 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/Journal.razor @@ -0,0 +1,88 @@ +@using Elsa.Studio.Workflows.Services +@using Variant = MudBlazor.Variant +@using Elsa.Studio.Workflows.Pages.WorkflowInstances.View.Models +@inherits StudioComponentBase +@using Microsoft.Extensions.Localization +@inject ILocalizer Localizer + + + + + + + + + + + + + + +
+ + + @{ + var journalEntry = context; + var record = journalEntry.Record; + var activityDescriptor = journalEntry.ActivityDescriptor; + var displaySettings = journalEntry.ActivityDisplaySettings; + var activityIcon = displaySettings?.Icon; + var isEven = journalEntry.IsEven; + var timelineAlign = !isEven ? TimelineAlign.Default : TimelineAlign.End; + var timeMetric = context.TimeMetric; + var displayName = string.IsNullOrWhiteSpace(record.ActivityName) ? activityDescriptor?.DisplayName : record.ActivityName; + var bgClass = journalEntry == SelectedEntry ? "gray lighten-3 rounded" : ""; + + var statusColor = + record.EventName switch + { + "Started" => Color.Primary, + "Completed" => Color.Success, + "Faulted" => Color.Error, + "Suspended" => Color.Warning, + "Resumed" => Color.Warning, + _ => Color.Default + }; + } + + + + + + @displayName + @record.EventName + + +
+ +
+
+ + @timeMetric.ToString("hh\\:mm\\:ss\\.fff") +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/Journal.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/Journal.razor.cs new file mode 100644 index 0000000..d004d07 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/Journal.razor.cs @@ -0,0 +1,209 @@ +using Elsa.Api.Client.RealTime.Messages; +using Elsa.Api.Client.Resources.WorkflowInstances.Enums; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Requests; +using Elsa.Studio.Workflows.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Pages.WorkflowInstances.View.Models; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web.Virtualization; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +/// Displays the journal for a workflow instance. +public partial class Journal : IAsyncDisposable +{ + private IList _currentEntries = null!; + private WorkflowInstance? _workflowInstance; + + /// Gets or sets a callback invoked when a journal entry is selected. + [Parameter] public Func? JournalEntrySelected { get; set; } + + [Inject] private IWorkflowInstanceService WorkflowInstanceService { get; set; } = null!; + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = null!; + [Inject] private IActivityDisplaySettingsRegistry ActivityDisplaySettingsRegistry { get; set; } = null!; + [Inject] private IWorkflowInstanceObserverFactory WorkflowInstanceObserverFactory { get; set; } = null!; + + private WorkflowInstance? WorkflowInstance { get; set; } + private IWorkflowInstanceObserver? WorkflowInstanceObserver { get; set; } + private TimeMetricMode TimeMetricMode { get; set; } = TimeMetricMode.Relative; + private bool ShowScopedEvents { get; set; } = true; + private bool ShowIncidents { get; set; } + private JournalEntry? SelectedEntry { get; set; } + private JournalFilter? JournalFilter { get; set; } + private Virtualize VirtualizeComponent { get; set; } = null!; + private int SelectedIndex { get; set; } = -1; + + /// Sets the workflow instance to display the journal for. + public async Task SetWorkflowInstanceAsync(WorkflowInstance workflowInstance, JournalFilter? filter = null) + { + WorkflowInstance = _workflowInstance = workflowInstance; + JournalFilter = filter; + await EnsureActivityDescriptorsAsync(); + await RefreshJournalAsync(); + await UpdateObserverAsync(); + StateHasChanged(); + } + + /// Clears the selection. + public void ClearSelection() + { + SelectedEntry = null; + SelectedIndex = -1; + StateHasChanged(); + } + + /// + protected override async Task OnInitializedAsync() + { + await EnsureActivityDescriptorsAsync(); + } + + /// + protected override async Task OnParametersSetAsync() + { + var hasDifferentState = _workflowInstance?.Id != WorkflowInstance?.Id || _workflowInstance?.Status != WorkflowInstance?.Status; + + if (_workflowInstance != WorkflowInstance) + { + _workflowInstance = WorkflowInstance; + + if (hasDifferentState) + await UpdateObserverAsync(); + } + } + + private async Task EnsureActivityDescriptorsAsync() => await ActivityRegistry.EnsureLoadedAsync(); + + private async Task RefreshJournalAsync() + { + if (VirtualizeComponent != null!) + await VirtualizeComponent.RefreshDataAsync(); + } + + private async Task UpdateObserverAsync() + { + if (WorkflowInstance?.Status == WorkflowStatus.Running) + await ObserveWorkflowInstanceAsync(); + } + + private TimeSpan GetTimeMetric(WorkflowExecutionLogRecord current, WorkflowExecutionLogRecord? previous) + { + return TimeMetricMode switch + { + TimeMetricMode.Relative => previous == null ? TimeSpan.Zero : current.Timestamp - previous.Timestamp, + TimeMetricMode.Accumulated => SumExecutionTime(current), + _ => throw new ArgumentOutOfRangeException() + }; + } + + private TimeSpan SumExecutionTime(WorkflowExecutionLogRecord current) => current.Timestamp - WorkflowInstance!.CreatedAt; + + private async ValueTask> FetchExecutionLogRecordsAsync(ItemsProviderRequest request) + { + if (WorkflowInstance == null) + return new([], 0); + + await EnsureActivityDescriptorsAsync(); + + var take = request.Count == 0 ? 10 : request.Count; + var skip = request.StartIndex > 0 ? request.StartIndex - 1 : 0; + var filter = new JournalFilter(); + + if (ShowScopedEvents) filter.ActivityNodeIds = JournalFilter?.ActivityNodeIds; + if (ShowIncidents) filter.EventNames = ["Faulted"]; + + filter.ExcludedActivityTypes = ["Elsa.Workflow", "Elsa.Flowchart"]; + + var response = await WorkflowInstanceService.GetJournalAsync(WorkflowInstance.Id, filter, skip, take); + var totalCount = request.StartIndex > 0 ? response.TotalCount - 1 : response.TotalCount; + var records = response.Items.ToArray(); + var localSkip = request.StartIndex > 0 ? 1 : 0; + var entries = records.Skip(localSkip).Select((record, index) => + { + var previousIndex = index - 1; + var previousRecord = previousIndex >= 0 ? records[previousIndex] : null; + var activityDescriptor = ActivityRegistry.Find(record.ActivityType, record.ActivityTypeVersion); + var activityDisplaySettings = ActivityDisplaySettingsRegistry.GetSettings(record.ActivityType); + var isEven = index % 2 == 0; + var timeMetric = GetTimeMetric(record, previousRecord); + + return new JournalEntry( + record, + activityDescriptor, + activityDisplaySettings, + isEven, + timeMetric); + }).ToList(); + + var selectedEntry = SelectedEntry; + _currentEntries = entries; + + // If the selected entry is still in the list, select it again. + SelectedEntry = entries.FirstOrDefault(x => x.Record.Id == selectedEntry?.Record.Id); + + return new(entries, (int)totalCount); + } + + private async Task DisposeObserverAsync() + { + if (WorkflowInstanceObserver != null) + { + WorkflowInstanceObserver.WorkflowJournalUpdated -= OnWorkflowJournalUpdatedAsync; + await WorkflowInstanceObserver.DisposeAsync(); + WorkflowInstanceObserver = null; + } + } + + private async Task ObserveWorkflowInstanceAsync() + { + await DisposeObserverAsync(); + WorkflowInstanceObserver = await WorkflowInstanceObserverFactory.CreateAsync(WorkflowInstance!.Id); + WorkflowInstanceObserver.WorkflowJournalUpdated += OnWorkflowJournalUpdatedAsync; + } + + private async Task OnWorkflowJournalUpdatedAsync(WorkflowExecutionLogUpdatedMessage message) + { + await InvokeAsync(RefreshJournalAsync); + } + + private async Task OnTimeMetricButtonToggleChanged(bool value) + { + TimeMetricMode = value ? TimeMetricMode.Accumulated : TimeMetricMode.Relative; + await RefreshJournalAsync(); + } + + private async Task OnScopeToggleChanged(bool value) + { + ShowScopedEvents = value; + await RefreshJournalAsync(); + } + + private async Task OnShowIncidentsToggleChanged(bool value) + { + ShowIncidents = value; + await RefreshJournalAsync(); + } + + private async Task OnJournalEntrySelected(int index) + { + if (index < 0 || index >= _currentEntries.Count) + { + SelectedEntry = null; + SelectedIndex = -1; + } + + var entry = index >= 0 && index < _currentEntries.Count ? _currentEntries[index] : null; + SelectedEntry = entry; + SelectedIndex = index; + + if (JournalEntrySelected != null && entry != null) + await JournalEntrySelected(entry); + } + + async ValueTask IAsyncDisposable.DisposeAsync() + { + await DisposeObserverAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/JournalEntryDetailsTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/JournalEntryDetailsTab.razor new file mode 100644 index 0000000..a709703 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/JournalEntryDetailsTab.razor @@ -0,0 +1,29 @@ +@using Elsa.Studio.Models +@inherits StudioComponentBase +@inject ILocalizer Localizer + + + @if (JournalEntry != null!) + { + var record = JournalEntry.Record; + var payload = ParsePayload(record.Payload); + + var eventInfo = new DataPanelModel + { + new DataPanelItem(Localizer["Name"], record.EventName), + new DataPanelItem(Localizer["Timestamp"], TimeFormatter.Format(record.Timestamp, "s")), + new DataPanelItem(Localizer["Message"], record.Message) + }; + + Merge(eventInfo, payload); + +
+ +
+ @Localizer["Event"] + +
+
+
+ } +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/JournalEntryDetailsTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/JournalEntryDetailsTab.razor.cs new file mode 100644 index 0000000..8d44e71 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/JournalEntryDetailsTab.razor.cs @@ -0,0 +1,56 @@ +using System.Text.Json; +using Elsa.Studio.Components; +using Elsa.Studio.Localization.Time; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Pages.WorkflowInstances.View.Models; +using Humanizer; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +/// Displays the details of a journal entry. +public partial class JournalEntryDetailsTab +{ + /// The journal entry. + [Parameter] public JournalEntry JournalEntry { get; set; } = default!; + + /// The height of the visible pane. + [Parameter] public int VisiblePaneHeight { get; set; } + + [Inject] private ITimeFormatter TimeFormatter { get; set; } = default!; + + private DataPanelModel ParsePayload(object? payload) + { + if (payload == null) + return new(); + + if (payload is not JsonElement jsonElement) + return [new DataPanelItem("Payload", payload.ToString())]; + + var properties = jsonElement.EnumerateObject().Where(x => !x.Name.StartsWith("_")); + var result = new DataPanelModel(); + + foreach (var property in properties) + { + var propertyName = property.Name.Pascalize(); + var propertyValue = property.Value; + var propertyValueAsString = propertyValue.ToString(); + result.Add(propertyName, propertyValueAsString); + } + + return result; + } + + private static void Merge(DataPanelModel target, DataPanelModel input) + { + foreach (var item in input) + { + var existingItem = target.FirstOrDefault(x => x.Label == item.Label); + + if (existingItem != null) + target.Remove(existingItem); + + target.Add(item); + } + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/RetriesTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/RetriesTab.razor new file mode 100644 index 0000000..3add61a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/RetriesTab.razor @@ -0,0 +1,45 @@ +@using Elsa.Api.Client.Resources.Resilience.Models +@inherits StudioComponentBase +@inject ILocalizer Localizer + + + + + # + @Localizer["Delay"] + @Localizer["Outcome"] + + + @{ + var record = context; + } + @record.AttemptNumber + @record.RetryDelay + @string.Join(", ", record.Details.Select(x => $"{x.Key}={x.Value}")) + + + + + + + @if (SelectedItem != null) + { +
+
+ @Localizer["Retry Details"] + +
+
+ } +
\ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/RetriesTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/RetriesTab.razor.cs new file mode 100644 index 0000000..394011e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/RetriesTab.razor.cs @@ -0,0 +1,39 @@ +using Elsa.Api.Client.Resources.Resilience.Models; +using Elsa.Studio.Models; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +/// Displays the details of an activity. +public partial class RetriesTab +{ + /// The activity execution record summaries. + [Parameter] public ICollection Retries { get; set; } = new List(); + + private RetryAttemptRecord? SelectedItem { get; set; } + private DataPanelModel SelectedRetryAttemptData { get; set; } = new(); + + + private void CreateSelectedItemDataModels(RetryAttemptRecord? record) + { + if (record == null) + { + SelectedRetryAttemptData = new(); + return; + } + + SelectedRetryAttemptData = new(); + + foreach (var detail in record.Details) + { + SelectedRetryAttemptData.Add(detail.Key, detail.Value); + } + } + + private void OnRetryAttemptClicked(TableRowClickEventArgs arg) + { + SelectedItem = arg.Item; + CreateSelectedItemDataModels(arg.Item); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDesigner.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDesigner.razor new file mode 100644 index 0000000..ca2b84a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDesigner.razor @@ -0,0 +1,55 @@ +@using Orientation = Radzen.Orientation +@using Elsa.Api.Client.Resources.WorkflowInstances.Enums +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer +@inherits StudioComponentBase + + + @if (WorkflowDefinition != null && WorkflowInstance != null!) + { + + + + + + + + + + } + + + @if (SelectedWorkflowExecutionLogRecord != null || SelectedActivity != null) + { + + @if (SelectedWorkflowExecutionLogRecord != null) + { + + + + } + + @if (SelectedActivity != null) + { + + + + + + + + } + + + } + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDesigner.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDesigner.razor.cs new file mode 100644 index 0000000..e843a8e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDesigner.razor.cs @@ -0,0 +1,404 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.RealTime.Messages; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.ActivityExecutions.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Enums; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.DomInterop.Contracts; +using Elsa.Studio.Workflows.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Extensions; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.Pages.WorkflowInstances.View.Models; +using Elsa.Studio.Workflows.Shared.Args; +using Elsa.Studio.Workflows.Shared.Components; +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.UI.Models; +using Microsoft.AspNetCore.Components; +using MudBlazor; +using Radzen; +using Radzen.Blazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +/// +/// Displays the workflow instance. +/// +public partial class WorkflowInstanceDesigner : IAsyncDisposable +{ + private WorkflowInstance? _workflowInstance = null!; + private RadzenSplitterPane _activityPropertiesPane = null!; + private DiagramDesignerWrapper? _designer; + private ActivityDetailsTab? _activityDetailsTab = null!; + private ActivityExecutionsTab? _activityExecutionsTab = null!; + private int _propertiesPaneHeight = 300; + private readonly Dictionary> _activityExecutionRecordsLookup = new(); + private readonly Dictionary _lastActivityExecutionRecordLookup = new(); + private Timer? _elapsedTimer; + + /// The workflow instance. + [Parameter] public WorkflowInstance? WorkflowInstance { get; set; } + + /// The workflow definition. + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// The path changed callback. + [Parameter] public EventCallback PathChanged { get; set; } + + /// The activity selected callback. + [Parameter] public EventCallback ActivitySelected { get; set; } + + /// An event that is invoked when the workflow definition is requested to be edited. + [Parameter] public EventCallback EditWorkflowDefinition { get; set; } + + /// Gets or sets the current selected sub-workflow. + [Parameter] public JsonObject? SelectedSubWorkflow { get; set; } + + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = null!; + [Inject] private IDiagramDesignerService DiagramDesignerService { get; set; } = null!; + [Inject] private IDomAccessor DomAccessor { get; set; } = null!; + [Inject] private IActivityVisitor ActivityVisitor { get; set; } = null!; + [Inject] private IActivityExecutionService ActivityExecutionService { get; set; } = null!; + [Inject] private IWorkflowInstanceObserverFactory WorkflowInstanceObserverFactory { get; set; } = null!; + [Inject] private IWorkflowInstanceService WorkflowInstanceService { get; set; } = null!; + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = null!; + [Inject] private NavigationManager NavigationManager { get; set; } = null!; + + private JsonObject? RootActivity => WorkflowDefinition?.Root; + private JsonObject? SelectedActivity { get; set; } + private ActivityDescriptor? ActivityDescriptor { get; set; } + private JournalEntry? SelectedWorkflowExecutionLogRecord { get; set; } + private IWorkflowInstanceObserver? WorkflowInstanceObserver { get; set; } = null!; + private ICollection SelectedActivityExecutions { get; set; } = new List(); + private ActivityExecutionRecord? LastActivityExecution { get; set; } + private Timer? _refreshTimer; + + private RadzenSplitterPane ActivityPropertiesPane + { + get => _activityPropertiesPane; + set + { + _activityPropertiesPane = value; + + // Prefix the ID with a non-numerical value so it can always be used as a query selector (sometimes, Radzen generates a unique ID starting with a number). + _activityPropertiesPane.UniqueID = $"pane-{value.UniqueID}"; + } + } + + private MudTabs PropertyTabs { get; set; } = null!; + private MudTabPanel EventsTabPanel { get; set; } = null!; + + /// Updates the selected sub-workflow. + public void UpdateSubWorkflow(JsonObject? obj) + { + SelectedSubWorkflow = obj; + StateHasChanged(); + } + + /// Selects the activity by its node ID. + public async Task SelectActivityAsync(string nodeId) + { + if (_designer == null) return; + await _designer.SelectActivityAsync(nodeId); + } + + /// Selects the activity by its ID. + public async Task SelectActivityByIdAsync(string activityId) + { + if (_designer == null) return; + await _designer.SelectActivityByActivityIdAsync(activityId); + } + + /// Sets the selected journal entry. + public async Task SelectWorkflowExecutionLogRecordAsync(JournalEntry entry) + { + var nodeId = entry.Record.NodeId; + SelectedWorkflowExecutionLogRecord = entry; + await SelectActivityAsync(nodeId); + StateHasChanged(); + } + + /// + protected override async Task OnInitializedAsync() + { + await ActivityRegistry.EnsureLoadedAsync(); + + if (WorkflowDefinition?.Root == null!) + return; + + await UpdateObserverAsync(); + } + + /// + protected override async Task OnParametersSetAsync() + { + var hasDifferentState = _workflowInstance?.Id != WorkflowInstance?.Id || _workflowInstance?.Status != WorkflowInstance?.Status; + + if (_workflowInstance != WorkflowInstance) + { + _workflowInstance = WorkflowInstance!; + + if (hasDifferentState) + await UpdateObserverAsync(); + } + } + + /// + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + if (WorkflowDefinition != null) + await HandleActivitySelectedAsync(WorkflowDefinition!.Root); + await UpdatePropertiesPaneHeightAsync(); + await UpdateObserverAsync(); + } + } + + private async Task UpdateObserverAsync() + { + if (WorkflowInstance?.Status == WorkflowStatus.Running) + { + await CreateObserverAsync(); + StartElapsedTimer(); + } + else + { + StopElapsedTimer(); + } + } + + private async Task CreateObserverAsync() + { + if (_workflowInstance == null || _designer == null) + return; + + await DisposeObserverAsync(); + var container = _designer.GetCurrentContainerActivityOrRoot(); + var observerContext = new WorkflowInstanceObserverContext + { + WorkflowInstanceId = _workflowInstance.Id, + ContainerActivity = container, + }; + WorkflowInstanceObserver = await WorkflowInstanceObserverFactory.CreateAsync(observerContext); + WorkflowInstanceObserver.ActivityExecutionLogUpdated += OnActivityExecutionLogUpdated; + } + + private async Task DisposeObserverAsync() + { + if (WorkflowInstanceObserver != null!) + { + WorkflowInstanceObserver.ActivityExecutionLogUpdated -= OnActivityExecutionLogUpdated; + await WorkflowInstanceObserver.DisposeAsync(); + WorkflowInstanceObserver = null; + } + } + + private async Task OnActivityExecutionLogUpdated(ActivityExecutionLogUpdatedMessage message) + { + if (_designer == null) return; + + foreach (var stats in message.Stats) + { + var activityNodeId = stats.ActivityNodeId; + var activityId = stats.ActivityId; + _activityExecutionRecordsLookup.Remove(activityNodeId); + _lastActivityExecutionRecordLookup.Remove(activityNodeId); + await _designer.UpdateActivityStatsAsync(activityId, Map(stats)); + } + + await InvokeAsync(StateHasChanged); + + // If we received an update for the selected activity, refresh the activity details. + var selectedActivityNodeId = SelectedActivity?.GetNodeId(); + var includesSelectedActivity = selectedActivityNodeId != null && message.Stats.Any(x => x.ActivityNodeId == selectedActivityNodeId); + + if (includesSelectedActivity) + { + await HandleActivitySelectedAsync(SelectedActivity!); + } + } + + private void StartElapsedTimer() + { + if (_elapsedTimer == null) + _elapsedTimer = new(_ => InvokeAsync(StateHasChanged), null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + } + + private void StopElapsedTimer() + { + if (_elapsedTimer != null) + { + _elapsedTimer?.Dispose(); + _elapsedTimer = null; + } + } + + private async Task HandleActivitySelectedAsync(JsonObject activity) + { + await StopRefreshActivityStatePeriodically(); + await InvokeAsync(async () => + { + var activityNodeId = activity.GetNodeId(); + SelectedActivity = activity; + ActivityDescriptor = ActivityRegistry.Find(activity.GetTypeName(), activity.GetVersion()); + SelectedActivityExecutions = await GetActivityExecutionRecordsAsync(activityNodeId); + StateHasChanged(); + _activityDetailsTab?.Refresh(); + + if (_activityExecutionsTab != null) + await _activityExecutionsTab.RefreshAsync(); + }); + + if (SelectedActivityExecutions.Any()) + { + if (LastActivityExecution != null && (!LastActivityExecution.IsFused() || LastActivityExecution.Status == ActivityStatus.Running)) + RefreshActivityStatePeriodically(LastActivityExecution.Id); + } + } + + private async Task> GetActivityExecutionRecordsAsync(string activityNodeId) + { + if (!_activityExecutionRecordsLookup.TryGetValue(activityNodeId, out var records)) + { + records = (await ActivityExecutionService.ListSummariesAsync(WorkflowInstance!.Id, activityNodeId)).ToList(); + _activityExecutionRecordsLookup[activityNodeId] = records; + _lastActivityExecutionRecordLookup.Remove(activityNodeId); + } + + if (records.Any()) + { + var lastRecord = records.Last(); + var lastActivityExecution = _lastActivityExecutionRecordLookup.GetValueOrDefault(activityNodeId); + + if (lastActivityExecution == null || lastActivityExecution.Id != lastRecord.Id) + { + lastActivityExecution = await ActivityExecutionService.GetAsync(lastRecord.Id); + _lastActivityExecutionRecordLookup[activityNodeId] = lastActivityExecution!; + } + + LastActivityExecution = lastActivityExecution; + } + else + { + LastActivityExecution = null; + } + + return records; + } + + private async Task UpdatePropertiesPaneHeightAsync() + { + var paneQuerySelector = $"#{ActivityPropertiesPane.UniqueID}"; + var visibleHeight = await DomAccessor.GetVisibleHeightAsync(paneQuerySelector); + _propertiesPaneHeight = (int)visibleHeight - 50; + } + + private async Task RefreshSelectedItemAsync(string activityExecutionRecordId) + { + if (LastActivityExecution != null) + { + _activityExecutionRecordsLookup.Remove(LastActivityExecution.ActivityNodeId); + SelectedActivityExecutions = await GetActivityExecutionRecordsAsync(LastActivityExecution.ActivityNodeId); + } + + await InvokeAsync(() => + { + StateHasChanged(); + _activityDetailsTab?.Refresh(); + }); + } + + private void RefreshActivityStatePeriodically(string activityExecutionRecordId) + { + async void Callback(object? _) + { + await RefreshSelectedItemAsync(activityExecutionRecordId); + + if (LastActivityExecution == null || (LastActivityExecution.IsFused() && LastActivityExecution.Status != ActivityStatus.Running)) + await StopRefreshActivityStatePeriodically(); + else + _refreshTimer?.Change(TimeSpan.FromSeconds(1), Timeout.InfiniteTimeSpan); + } + + _refreshTimer = new(Callback, null, TimeSpan.FromSeconds(1), Timeout.InfiniteTimeSpan); + } + + private async Task StopRefreshActivityStatePeriodically() + { + if (_refreshTimer != null) + { + await _refreshTimer.DisposeAsync(); + _refreshTimer = null; + } + } + + private static ActivityStats Map(ActivityExecutionStats source) + { + return new() + { + Faulted = source.IsFaulted, + Blocked = source.IsBlocked, + Completed = source.CompletedCount, + Started = source.StartedCount, + Uncompleted = source.UncompletedCount, + Metadata = source.Metadata, + }; + } + + private async Task OnActivitySelected(JsonObject activity) + { + await HandleActivitySelectedAsync(activity); + + var activitySelected = ActivitySelected; + + if (activitySelected.HasDelegate) + await activitySelected.InvokeAsync(activity); + } + + private async Task OnResize(RadzenSplitterResizeEventArgs arg) + { + await UpdatePropertiesPaneHeightAsync(); + } + + private Task OnEditClicked() + { + var definitionId = WorkflowDefinition!.DefinitionId; + + if (SelectedSubWorkflow != null) + { + var typeName = SelectedSubWorkflow.GetTypeName(); + var version = SelectedSubWorkflow.GetVersion(); + var descriptor = ActivityRegistry.Find(typeName, version); + var isWorkflowActivity = descriptor != null && + descriptor.CustomProperties.TryGetValue("RootType", out var rootTypeNameElement) && + ((JsonElement)rootTypeNameElement).GetString() == "WorkflowDefinitionActivity"; + if (isWorkflowActivity) + { + definitionId = SelectedSubWorkflow.GetWorkflowDefinitionId(); + } + } + + var editWorkflowDefinition = EditWorkflowDefinition; + + if (editWorkflowDefinition.HasDelegate) + return editWorkflowDefinition.InvokeAsync(definitionId); + + NavigationManager.NavigateTo($"workflows/definitions/{definitionId}/edit"); + return Task.CompletedTask; + } + + async ValueTask IAsyncDisposable.DisposeAsync() + { + StopElapsedTimer(); + await DisposeObserverAsync(); + + if (_refreshTimer != null) + await _refreshTimer.DisposeAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDetails.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDetails.razor new file mode 100644 index 0000000..6958842 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDetails.razor @@ -0,0 +1,144 @@ +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@using Microsoft.Extensions.Localization +@inject ILocalizer Localizer + +@if (WorkflowDefinition != null && WorkflowInstance != null) +{ + + + +
+ @Localizer["Workflow"] + +
+
+ + @if (WorkflowInstanceSubWorkflowData.Any()) + { + +
+ @Localizer["Sub-Workflow"] + +
+
+ } +
+ + @if (IncidentsData.Any()) + { + + + @foreach (var incident in IncidentsData) + { + + +
+ @incident.SingleOrDefault(i=>i.Label == "Message")?.Text +
+
+ + + + + +
+ } +
+
+ } + else + { + + No incidents + + } +
+ + +
+ @if (WorkflowVariableData.Any()) + { + + } + else + { + + @Localizer["No variables"] + + } +
+
+
+ + +
+ @Localizer["Inputs"] + @if (WorkflowInputData.Any()) + { + + } + else + { + + @Localizer["No inputs"] + + } +
+
+ @Localizer["Outputs"] + @if (WorkflowOutputData.Any()) + { + + } + else + { + + @Localizer["No outputs"] + + } +
+
+ + @if (SubWorkflowInputData.Any()) + { +
+ @Localizer["Sub-Workflow Inputs"] + +
+ } + @if (SubWorkflowOutputData.Any()) + { +
+ @Localizer["Sub-Workflow Outputs"] + +
+ } +
+
+
+} + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDetails.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDetails.razor.cs new file mode 100644 index 0000000..0868a12 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceDetails.razor.cs @@ -0,0 +1,347 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityExecutions.Models; +using Elsa.Api.Client.Resources.LogPersistenceStrategies; +using Elsa.Api.Client.Resources.StorageDrivers.Models; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Enums; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Enums; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Api.Client.Serialization; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Localization.Time; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Humanizer; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +/// +/// Displays details about a workflow instance. +/// +public partial class WorkflowInstanceDetails +{ + private readonly JsonSerializerOptions _serializerOptions = SerializerOptions.LogPersistenceConfigSerializerOptions; + + private WorkflowInstance? _workflowInstance; + + private ActivityExecutionRecord? _workflowActivityExecutionRecord; + private ICollection _variables = []; + + /// + /// Gets or sets the workflow instance to display. + /// + [Parameter] public WorkflowInstance? WorkflowInstance { get; set; } + + /// + /// Gets or sets the workflow definition associated with the workflow instance. + /// + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// + /// Gets or sets the current selected sub-workflow. + /// + [Parameter] public JsonObject? SelectedSubWorkflow { get; set; } + + /// + /// Gets or sets the current selected sub-workflow executions. + /// + [Parameter] public ICollection? SelectedSubWorkflowExecutions { get; set; } + + /// + /// Gets or sets the current selected incident activity id. + /// + [Parameter] public Func? IncidentActivityNodeIdClicked { get; set; } + + [Inject] private IStorageDriverService StorageDriverService { get; set; } = null!; + [Inject] private IWorkflowInstanceService WorkflowInstanceService { get; set; } = null!; + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = null!; + [Inject] private IActivityExecutionService ActivityExecutionService { get; set; } = null!; + [Inject] private ITimeFormatter TimeFormatter { get; set; } = null!; + + private IDictionary StorageDriverLookup { get; set; } = new Dictionary(); + + private DataPanelModel WorkflowInstanceData + { + get + { + if (_workflowInstance == null) + return new(); + + return new() + { + new DataPanelItem("ID", _workflowInstance.Id), + new DataPanelItem(Localizer["Name"], _workflowInstance.Name ?? WorkflowDefinition?.Name), + new DataPanelItem(Localizer["Definition ID"], _workflowInstance.DefinitionId, $"/workflows/definitions/{_workflowInstance.DefinitionId}/edit"), + new DataPanelItem(Localizer["Definition version"], _workflowInstance.Version.ToString()), + new DataPanelItem(Localizer["Definition version ID"], _workflowInstance.DefinitionVersionId), + new DataPanelItem(Localizer["Correlation ID"], _workflowInstance.CorrelationId), + new DataPanelItem(Localizer["Incident Strategy"], GetIncidentStrategyDisplayName(WorkflowDefinition?.Options.IncidentStrategyType)), + new DataPanelItem(Localizer["Status"], _workflowInstance.Status.ToString()), + new DataPanelItem(Localizer["Sub status"], _workflowInstance.SubStatus.ToString()), + new DataPanelItem(Localizer["Incidents"], _workflowInstance.IncidentCount.ToString()), + new DataPanelItem(Localizer["Created"], TimeFormatter.Format(_workflowInstance.CreatedAt)), + new DataPanelItem(Localizer["Updated"], TimeFormatter.Format(_workflowInstance.UpdatedAt)), + new DataPanelItem(Localizer["Finished"], TimeFormatter.Format(_workflowInstance.FinishedAt)), + new DataPanelItem(Localizer["Log Persistence Strategy"], GetLogPersistenceConfigurationDisplayName(GetLogPersistenceConfiguration()?.StrategyType)) + }; + } + } + + private LogPersistenceConfiguration? GetLogPersistenceConfiguration() + { + if (!WorkflowDefinition!.CustomProperties.TryGetValue("logPersistenceConfig", out var value) || value == null!) + return null; + + + var configJson = ((JsonElement)value).GetProperty("default"); + var config = JsonSerializer.Deserialize(configJson, _serializerOptions); + return config; + } + + private DataPanelModel WorkflowVariableData + { + get + { + return WorkflowDefinition == null + ? new DataPanelModel() + : new DataPanelModel(WorkflowDefinition.Variables.Select(entry => new DataPanelItem(entry.Name, GetVariableValue(entry)))); + } + } + + private DataPanelModel WorkflowInputData + { + get + { + if (_workflowInstance == null || WorkflowDefinition == null) + return new(); + + var inputData = new DataPanelModel(); + foreach (var input in WorkflowDefinition.Inputs) + { + _workflowInstance.WorkflowState.Input.TryGetValue(input.Name, out object? inputFromInstance); + var inputName = !string.IsNullOrWhiteSpace(input.DisplayName) ? input.DisplayName : input.Name; + inputData.Add(inputName, inputFromInstance?.ToString()); + } + + return inputData; + } + } + + private DataPanelModel WorkflowOutputData + { + get + { + if (_workflowInstance == null || WorkflowDefinition == null) + return new DataPanelModel(); + + var outputData = new DataPanelModel(); + foreach (var output in WorkflowDefinition.Outputs) + { + _workflowInstance.WorkflowState.Output.TryGetValue(output.Name, out object? outputFromInstance); + var outputName = !string.IsNullOrWhiteSpace(output.DisplayName) ? output.DisplayName : output.Name; + outputData.Add(outputName, outputFromInstance?.ToString()); + } + + return outputData; + } + } + + private DataPanelModel WorkflowInstanceSubWorkflowData + { + get + { + if (SelectedSubWorkflow == null) + return new(); + + var typeName = SelectedSubWorkflow.GetTypeName(); + var version = SelectedSubWorkflow.GetVersion(); + var descriptor = ActivityRegistry.Find(typeName, version); + var isWorkflowActivity = descriptor != null && + descriptor.CustomProperties.TryGetValue("RootType", out var rootTypeNameElement) && + ((JsonElement)rootTypeNameElement).GetString() == "WorkflowDefinitionActivity"; + var workflowDefinitionId = isWorkflowActivity ? SelectedSubWorkflow.GetWorkflowDefinitionId() : null; + + if (workflowDefinitionId == null) + return new(); + + return new() + { + new DataPanelItem("ID", SelectedSubWorkflow.GetId()), + new DataPanelItem(Localizer["Name"], SelectedSubWorkflow.GetName()), + new DataPanelItem(Localizer["Type"], SelectedSubWorkflow.GetTypeName()), + new DataPanelItem(Localizer["Definition ID"], workflowDefinitionId, $"/workflows/definitions/{workflowDefinitionId}/edit"), + new DataPanelItem(Localizer["Definition version"], SelectedSubWorkflow.GetVersion().ToString()), + }; + } + } + + private IEnumerable IncidentsData + { + get + { + if (_workflowInstance == null) + return new List(); + + return _workflowInstance.WorkflowState.Incidents + .Select(i => new DataPanelModel + { + new DataPanelItem("ActivityId", i.ActivityId), + new DataPanelItem("ActivityNodeId", i.ActivityNodeId, null, () => OnIncidentActivityNodeIdClicked(i.ActivityNodeId)), + new DataPanelItem("Message", i.Exception?.Message ?? ""), + new DataPanelItem("InnerException", i.Exception?.InnerException != null + ? i.Exception?.InnerException.Type + ": " + i.Exception?.InnerException.Message + : ""), + new DataPanelItem("StackTrace", i.Exception?.StackTrace ?? "") + }); + } + } + + private async Task OnIncidentActivityNodeIdClicked(string? activityNodeId) + { + if (IncidentActivityNodeIdClicked != null && !string.IsNullOrWhiteSpace(activityNodeId)) + await IncidentActivityNodeIdClicked(activityNodeId); + } + + private DataPanelModel SubWorkflowInputData + { + get + { + if (SelectedSubWorkflowExecutions == null || SelectedSubWorkflow == null) + return new(); + + var execution = SelectedSubWorkflowExecutions.LastOrDefault(); + var inputData = new DataPanelModel(); + var activityState = execution?.ActivityState; + if (activityState != null) + { + var activityDescriptor = ActivityRegistry.Find(SelectedSubWorkflow.GetTypeName(), SelectedSubWorkflow.GetVersion())!; + foreach (var inputDescriptor in activityDescriptor.Inputs) + { + var inputValue = activityState.TryGetValue(inputDescriptor.Name, out var value) ? value : null; + inputData.Add(inputDescriptor.DisplayName ?? inputDescriptor.Name, inputValue?.ToString()); + } + } + + return inputData; + } + } + + private DataPanelModel SubWorkflowOutputData + { + get + { + if (SelectedSubWorkflowExecutions == null || SelectedSubWorkflow == null) + return new(); + + var execution = SelectedSubWorkflowExecutions.LastOrDefault(); + var outputData = new DataPanelModel(); + + if (execution != null) + { + var outputs = execution.Outputs; + var activityDescriptor = + ActivityRegistry.Find(SelectedSubWorkflow.GetTypeName(), SelectedSubWorkflow.GetVersion())!; + var outputDescriptors = activityDescriptor.Outputs; + + foreach (var outputDescriptor in outputDescriptors) + { + var outputValue = outputs != null + ? outputs.TryGetValue(outputDescriptor.Name, out var value) ? value : null + : null; + outputData.Add(outputDescriptor.DisplayName ?? outputDescriptor.Name, outputValue?.ToString()); + } + } + + return outputData; + } + } + + /// Updates the selected sub-workflow. + public async Task UpdateSubWorkflowAsync(JsonObject? obj) + { + SelectedSubWorkflow = obj; + SelectedSubWorkflowExecutions = obj == null + ? null + : (await ActivityExecutionService.ListAsync(WorkflowInstance!.Id, obj.GetNodeId())).ToList(); + StateHasChanged(); + } + + /// + protected override async Task OnInitializedAsync() + { + var drivers = await StorageDriverService.GetStorageDriversAsync(); + StorageDriverLookup = drivers.ToDictionary(x => x.TypeName); + } + + /// + protected override async Task OnParametersSetAsync() + { + if (_workflowInstance != WorkflowInstance) + { + _workflowInstance = WorkflowInstance; + + if (_workflowInstance != null) + { + await GetWorkflowActivityExecutionRecordAsync(_workflowInstance.Id); + await GetVariablesAsync(_workflowInstance.Id); + } + } + } + + private async Task GetWorkflowActivityExecutionRecordAsync(string workflowInstanceId) + { + _workflowActivityExecutionRecord = await GetLastWorkflowActivityExecutionRecordAsync(workflowInstanceId); + } + + private async Task GetVariablesAsync(string workflowInstanceId) + { + _variables = (await WorkflowInstanceService.GetVariablesAsync(workflowInstanceId)).ToList(); + } + + private async Task GetLastWorkflowActivityExecutionRecordAsync(string workflowInstanceId) + { + var rootWorkflowActivityExecutionContext = WorkflowInstance?.WorkflowState.ActivityExecutionContexts.FirstOrDefault(x => x.ParentContextId == null); + if (rootWorkflowActivityExecutionContext == null) return null; + var rootWorkflowActivityNodeId = rootWorkflowActivityExecutionContext.ScheduledActivityNodeId; + var records = await ActivityExecutionService.ListAsync(workflowInstanceId, rootWorkflowActivityNodeId); + return records.MaxBy(x => x.StartedAt); + } + + private string GetStorageDriverDisplayName(string? storageDriverTypeName) + { + if (storageDriverTypeName == null) + return "None"; + + return !StorageDriverLookup.TryGetValue(storageDriverTypeName, out var descriptor) + ? storageDriverTypeName + : descriptor.DisplayName; + } + + [RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Deserialize(JsonSerializerOptions)")] + private string GetVariableValue(Variable variable) + { + var resolvedVariable = _variables.FirstOrDefault(x => x.Id == variable.Id); + return resolvedVariable?.Value?.ToString() ?? string.Empty; + } + + private static string GetIncidentStrategyDisplayName(string? incidentStrategyTypeName) + { + return incidentStrategyTypeName + ?.Split(",", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).First() + .Split(".", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Last() + .Replace("Strategy", "") + .Humanize() ?? "Default"; + } + + private static string? GetLogPersistenceConfigurationDisplayName(string? logPersistenceConfigurationTypeName) + { + //"Elsa.Workflows.LogPersistence.Strategies.Include, Elsa.Workflows.Core" + return logPersistenceConfigurationTypeName?.Split(",")[0].Split(".")[^1] ; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceWorkspace.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceWorkspace.razor new file mode 100644 index 0000000..02650f2 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceWorkspace.razor @@ -0,0 +1,39 @@ +@using Orientation = Radzen.Orientation +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + + + + + + + + @if (WorkflowInstance != null) + { + + + + } + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceWorkspace.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceWorkspace.razor.cs new file mode 100644 index 0000000..86b7656 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Components/WorkflowInstanceWorkspace.razor.cs @@ -0,0 +1,58 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Studio.Workflows.Pages.WorkflowInstances.View.Models; +using Elsa.Studio.Workflows.Shared.Args; +using Elsa.Studio.Workflows.UI.Contracts; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; + +public partial class WorkflowInstanceWorkspace : IWorkspace +{ + private WorkflowInstanceDetails _workflowInstanceDetails = default!; + private WorkflowInstanceDesigner _workflowInstanceDesigner = default!; + private MudDynamicTabs _dynamicTabs = default!; + + /// Gets or sets the workflow instance to view. + [Parameter] public WorkflowInstance? WorkflowInstance { get; set; } + + /// Gets or sets the workflow definition of the workflow instance to view. + [Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; } + + /// An event callback that is invoked when the current workflow graph path has changed. + [Parameter] public EventCallback PathChanged { get; set; } + + /// An event callback that is invoked when an activity is selected. + [Parameter] public EventCallback ActivitySelected { get; set; } + + /// An event that is invoked when a workflow definition is edited. + [Parameter] public EventCallback EditWorkflowDefinition { get; set; } + /// + public bool IsReadOnly => true; + + /// + public bool HasWorkflowEditPermission => true; + + /// Selects the associated activity in the designer and activates its Event tab. + public async Task SelectWorkflowExecutionLogRecordAsync(JournalEntry entry) + { + await _workflowInstanceDesigner.SelectWorkflowExecutionLogRecordAsync(entry); + } + + /// Selects the associated activity in the designer and activates its Event tab. + public async Task OnIncidentActivityNodeIdClicked(string activityNodeId) + { + await _workflowInstanceDesigner.SelectActivityAsync(activityNodeId); + } + + private async Task OnPathChanged(DesignerPathChangedArgs args) + { + await _workflowInstanceDetails.UpdateSubWorkflowAsync(args.ParentActivity); + _workflowInstanceDesigner.UpdateSubWorkflow(args.ParentActivity); + + if(PathChanged.HasDelegate) + await PathChanged.InvokeAsync(args); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Models/JournalEntry.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Models/JournalEntry.cs new file mode 100644 index 0000000..9d246e2 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Models/JournalEntry.cs @@ -0,0 +1,13 @@ +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Studio.Workflows.UI.Models; + +namespace Elsa.Studio.Workflows.Pages.WorkflowInstances.View.Models; + +public record JournalEntry( + WorkflowExecutionLogRecord Record, + ActivityDescriptor? ActivityDescriptor, + ActivityDisplaySettings? ActivityDisplaySettings, + bool IsEven, + TimeSpan TimeMetric +); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Models/TimeMetricMode.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Models/TimeMetricMode.cs new file mode 100644 index 0000000..d97bb8b --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/Models/TimeMetricMode.cs @@ -0,0 +1,14 @@ +namespace Elsa.Studio.Workflows.Pages.WorkflowInstances.View.Models; + +public enum TimeMetricMode +{ + /// + /// Show the delta between the current and previous log entry. + /// + Relative, + + /// + /// Show the accumulated time since the workflow instance started until the current log entry. + /// + Accumulated +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/WorkflowInstanceViewer.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/WorkflowInstanceViewer.razor new file mode 100644 index 0000000..620461d --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/WorkflowInstanceViewer.razor @@ -0,0 +1,17 @@ +@inherits StudioComponentBase +@using Orientation = Radzen.Orientation + + + + + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/WorkflowInstanceViewer.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/WorkflowInstanceViewer.razor.cs new file mode 100644 index 0000000..372c7f7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowInstanceViewer/WorkflowInstanceViewer.razor.cs @@ -0,0 +1,117 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.RealTime.Messages; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Enums; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Api.Client.Resources.WorkflowInstances.Requests; +using Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components; +using Elsa.Studio.Workflows.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Pages.WorkflowInstances.View.Models; +using Elsa.Studio.Workflows.Shared.Args; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Components.WorkflowInstanceViewer; + +/// The index page for viewing a workflow instance. +public partial class WorkflowInstanceViewer : IAsyncDisposable +{ + private WorkflowInstance _workflowInstance = default!; + private WorkflowDefinition _workflowDefinition = default!; + private WorkflowInstanceWorkspace _workspace = default!; + private IWorkflowInstanceObserver? _workflowInstanceObserver = default!; + + /// The ID of the workflow instance to view. + [Parameter] public string InstanceId { get; set; } = default!; + + /// An event that is invoked when a workflow definition is edited. + [Parameter] public EventCallback EditWorkflowDefinition { get; set; } + + [Inject] private IWorkflowInstanceService WorkflowInstanceService { get; set; } = default!; + + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = default!; + [Inject] private IWorkflowInstanceObserverFactory WorkflowInstanceObserverFactory { get; set; } = default!; + + private Journal Journal { get; set; } = default!; + + /// + protected override async Task OnInitializedAsync() + { + var instance = await WorkflowInstanceService.GetAsync(InstanceId) ?? throw new InvalidOperationException($"Workflow instance with ID {InstanceId} not found."); + var workflowDefinition = await WorkflowDefinitionService.FindByIdAsync(instance.DefinitionVersionId); + _workflowInstance = instance; + _workflowDefinition = workflowDefinition!; + await SelectWorkflowInstanceAsync(instance); + + if (_workflowInstance.Status == WorkflowStatus.Running) + await ObserveWorkflowInstanceAsync(); + } + + private async Task ObserveWorkflowInstanceAsync() + { + await DisposeObserverAsync(); + _workflowInstanceObserver = await WorkflowInstanceObserverFactory.CreateAsync(_workflowInstance.Id); + _workflowInstanceObserver.WorkflowInstanceUpdated += OnWorkflowInstanceUpdatedAsync; + } + + private async Task DisposeObserverAsync() + { + if (_workflowInstanceObserver != null) + { + _workflowInstanceObserver.WorkflowInstanceUpdated -= OnWorkflowInstanceUpdatedAsync; + await _workflowInstanceObserver.DisposeAsync(); + _workflowInstanceObserver = null; + } + } + + private async Task SelectWorkflowInstanceAsync(WorkflowInstance instance) + { + // Select activity node IDs that are direct children of the root. + var activityNodeIds = _workflowDefinition.Root.GetActivities().Select(x => x.GetNodeId()).ToList(); + var filter = new JournalFilter + { + ActivityNodeIds = activityNodeIds + }; + await Journal.SetWorkflowInstanceAsync(instance, filter); + } + + private async Task OnWorkflowInstanceUpdatedAsync(WorkflowInstanceUpdatedMessage message) + { + var workflowInstance = (await WorkflowInstanceService.GetAsync(_workflowInstance.Id))!; + await InvokeAsync(async () => + { + _workflowInstance = workflowInstance; + StateHasChanged(); + + if (_workflowInstance.Status == WorkflowStatus.Finished) + await Journal.SetWorkflowInstanceAsync(_workflowInstance); + }); + } + + private async Task OnDesignerPathChanged(DesignerPathChangedArgs args) + { + var activityNodeIds = args.ContainerActivity.GetActivities().Select(x => x.GetNodeId()).ToList(); + var filter = new JournalFilter + { + ActivityNodeIds = activityNodeIds + }; + await Journal.SetWorkflowInstanceAsync(_workflowInstance, filter); + } + + private async Task OnWorkflowExecutionLogRecordSelected(JournalEntry entry) + { + await _workspace.SelectWorkflowExecutionLogRecordAsync(entry); + } + + private Task OnActivitySelected(JsonObject arg) + { + Journal.ClearSelection(); + return Task.CompletedTask; + } + + async ValueTask IAsyncDisposable.DisposeAsync() + { + await DisposeObserverAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Constants/ZoneNames.cs b/src/modules/Elsa.Studio.Workflows/Constants/ZoneNames.cs new file mode 100644 index 0000000..39cc55f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Constants/ZoneNames.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Workflows.Constants; + +/// +/// Provides zone names. +/// +public static class ZoneNames +{ + /// + /// The zone for the workflow definition properties. + /// + public const string WorkflowDefinitionProperties = "workflow-definition-properties"; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Contracts/IWorkflowInstanceObserver.cs b/src/modules/Elsa.Studio.Workflows/Contracts/IWorkflowInstanceObserver.cs new file mode 100644 index 0000000..553d315 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Contracts/IWorkflowInstanceObserver.cs @@ -0,0 +1,16 @@ +using Elsa.Api.Client.RealTime.Messages; + +namespace Elsa.Studio.Workflows.Contracts; + +/// Defines a contract for observing workflow instance events such as execution log updates and instance updates. +public interface IWorkflowInstanceObserver : IAsyncDisposable +{ + /// An event that is raised when the workflow execution log is updated. + event Func WorkflowJournalUpdated; + + /// An event that is raised when the activity execution log is updated. + event Func ActivityExecutionLogUpdated; + + /// An event that is raised when the workflow instance is updated. + event Func WorkflowInstanceUpdated; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Contracts/IWorkflowInstanceObserverFactory.cs b/src/modules/Elsa.Studio.Workflows/Contracts/IWorkflowInstanceObserverFactory.cs new file mode 100644 index 0000000..70c803c --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Contracts/IWorkflowInstanceObserverFactory.cs @@ -0,0 +1,13 @@ +using Elsa.Studio.Workflows.Models; + +namespace Elsa.Studio.Workflows.Contracts; + +/// A factory for creating instances. +public interface IWorkflowInstanceObserverFactory +{ + /// Creates a new instance. + Task CreateAsync(string workflowInstanceId); + + /// Creates a new instance. + Task CreateAsync(WorkflowInstanceObserverContext context); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDesigner.razor b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDesigner.razor new file mode 100644 index 0000000..6f2c8fd --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDesigner.razor @@ -0,0 +1,17 @@ +@using System.Text.Json.Nodes +@using Elsa.Api.Client.Extensions + + + @if (Activity != null) + { + + } + + + +@code { + + [Parameter] + public JsonObject? Activity { get; set; } + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDesignerProvider.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDesignerProvider.cs new file mode 100644 index 0000000..891cc62 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDesignerProvider.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Workflows.UI.Contracts; + +namespace Elsa.Studio.Workflows.DiagramDesigners.Fallback; + +public class FallbackDesignerProvider : IDiagramDesignerProvider +{ + public double Priority => -1000; + public bool GetSupportsActivity(JsonObject activity) => true; + + public IDiagramDesigner GetEditor() => new FallbackDiagramDesigner(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDiagramDesigner.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDiagramDesigner.cs new file mode 100644 index 0000000..a493a44 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Fallback/FallbackDiagramDesigner.cs @@ -0,0 +1,59 @@ +using System.Text.Json.Nodes; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.UI.Contexts; +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.UI.Models; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.DiagramDesigners.Fallback; + +/// A fallback diagram designer that displays a simplified view of the workflow. +public class FallbackDiagramDesigner : IDiagramDesigner +{ + private JsonObject _activity = default!; + + /// + public Task LoadRootActivityAsync(JsonObject activity, IDictionary? activityStatsMap) + { + _activity = activity; + return Task.CompletedTask; + } + + /// + public Task UpdateActivityAsync(string id, JsonObject activity) + { + return Task.CompletedTask; + } + + /// + public Task UpdateActivityStatsAsync(string id, ActivityStats stats) + { + return Task.CompletedTask; + } + + /// + public Task SelectActivityAsync(string id) + { + return Task.CompletedTask; + } + + /// + public Task ReadRootActivityAsync() + { + return Task.FromResult(_activity); + } + + /// + public RenderFragment DisplayDesigner(DisplayContext context) + { + _activity = context.Activity; + + return builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, nameof(FallbackDesigner.Activity), _activity); + builder.CloseComponent(); + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor new file mode 100644 index 0000000..9580bac --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor @@ -0,0 +1,19 @@ +@if (IsReadOnly) + +{ +
+ +
+} + +else + +{ +
+ +
+} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor.cs new file mode 100644 index 0000000..bf35424 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor.cs @@ -0,0 +1,197 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.ActivityDescriptors.Enums; +using Elsa.Api.Client.Resources.ActivityDescriptors.Models; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Designer.Components; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.UI.Args; +using Elsa.Studio.Workflows.UI.Models; +using Humanizer; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace Elsa.Studio.Workflows.DiagramDesigners.Flowcharts; + +/// +/// A wrapper around the component that provides interactivity such as drag and drop and displaying the designer in edit or read-only mode. +/// +public partial class FlowchartDesignerWrapper +{ + /// + /// The flowchart to display. + /// + [Parameter] public JsonObject Flowchart { get; set; } = default!; + + /// + /// A map of activity stats. + /// + [Parameter] public IDictionary? ActivityStats { get; set; } + + /// + /// Whether the designer is read-only. + /// + [Parameter] public bool IsReadOnly { get; set; } + + /// + /// An event raised when an activity is selected. + /// + [Parameter] public EventCallback ActivitySelected { get; set; } + + [Parameter] public EventCallback ActivityUpdated { get; set; } + + /// + /// An event raised when an embedded port is selected. + /// + [Parameter] public EventCallback ActivityEmbeddedPortSelected { get; set; } + + /// + /// An event raised when an activity is double-clicked. + /// + [Parameter] public EventCallback ActivityDoubleClick { get; set; } + + /// + /// An event raised when the graph is updated. + /// + [Parameter] public EventCallback GraphUpdated { get; set; } + + [CascadingParameter] private DragDropManager DragDropManager { get; set; } = default!; + [Inject] private IIdentityGenerator IdentityGenerator { get; set; } = default!; + [Inject] private IActivityNameGenerator ActivityNameGenerator { get; set; } = default!; + private FlowchartDesigner Designer { get; set; } = default!; + + /// + /// Loads the specified flowchart activity into the designer. + /// + /// The flowchart activity to load. + /// A map of activity stats. + public async Task LoadFlowchartAsync(JsonObject activity, IDictionary? activityStats = default) + { + if (activity.GetTypeName() != "Elsa.Flowchart") + throw new ArgumentException("Activity must be an Elsa.Flowchart", nameof(activity)); + + Flowchart = activity; + ActivityStats = activityStats; + await Designer.LoadFlowchartAsync(activity, activityStats); + } + + /// + /// Updates the specified activity in the flowchart. + /// + /// The ID of the activity to update. + /// The activity to update. + /// Thrown if the designer is read-only. + public async Task UpdateActivityAsync(string id, JsonObject activity) + { + if (IsReadOnly) + throw new InvalidOperationException("Cannot update activity because the designer is read-only."); + + if (activity != Flowchart) + await Designer.UpdateActivityAsync(id, activity); + } + + /// + /// Updates the stats of the specified activity. + /// + /// The ID of the activity to update. + /// The stats to update. + public async Task UpdateActivityStatsAsync(string id, ActivityStats stats) => await Designer.UpdateActivityStatsAsync(id, stats); + + /// + /// Selects the specified activity in the flowchart. + /// + /// The ID of the activity to select. + public async Task SelectActivityAsync(string id) => await Designer.SelectActivityAsync(id); + + /// + /// Reads the root activity from the flowchart. + /// + /// The root activity. + public async Task ReadRootActivityAsync() => await Designer.ReadFlowchartAsync(); + + /// + /// Zooms the designer to fit the content. + /// + public async Task ZoomToFitAsync() => await Designer.ZoomToFitAsync(); + + /// + /// Centers the content of the designer. + /// + public async Task CenterContentAsync() => await Designer.CenterContentAsync(); + + /// + /// Auto layouts the flowchart. + /// + public async Task AutoLayoutAsync() => await Designer.AutoLayoutAsync(Flowchart, ActivityStats); + + private async Task AddNewActivityAsync(ActivityDescriptor activityDescriptor, double x, double y) + { + var activities = Flowchart.GetActivities().ToList(); + var newActivityId = IdentityGenerator.GenerateId(); + + var newActivity = new JsonObject(new Dictionary + { + ["id"] = newActivityId, + ["nodeId"] = $"{Flowchart.GetNodeId()}:{newActivityId}", + ["name"] = ActivityNameGenerator.GenerateNextName(activities, activityDescriptor), + ["type"] = activityDescriptor.TypeName, + ["version"] = activityDescriptor.Version, + }); + + newActivity.SetDesignerMetadata(new ActivityDesignerMetadata + { + Position = new Position(x, y) + }); + + // Copy constructor values from the activity descriptor. + foreach (var property in activityDescriptor.ConstructionProperties) + { + var valueNode = JsonSerializer.SerializeToNode(property.Value); + var propertyName = property.Key.Camelize(); + newActivity.SetProperty(valueNode, propertyName); + } + + // If the activity is a trigger, and it's the first trigger on the flowchart, set the trigger property to true. + if (activityDescriptor.Kind == ActivityKind.Trigger && activities.All(activity => activity.GetCanStartWorkflow() != true)) + newActivity.SetCanStartWorkflow(true); + + await Designer.AddActivityAsync(newActivity); + + if (ActivitySelected.HasDelegate) + await ActivitySelected.InvokeAsync(newActivity); + } + + private void OnDragOver(DragEventArgs e) + { + if (DragDropManager.Payload is not ActivityDescriptor) + { + e.DataTransfer.DropEffect = "none"; + return; + } + + e.DataTransfer.DropEffect = "move"; + } + + private async Task OnDrop(DragEventArgs e) + { + if (DragDropManager.Payload is not ActivityDescriptor activityDescriptor) + return; + + var x = e.PageX; + var y = e.PageY; + + await AddNewActivityAsync(activityDescriptor, x, y); + } + + private async Task OnCanvasSelected() + { + if (ActivitySelected.HasDelegate) + await ActivitySelected.InvokeAsync(Flowchart); + } + + private async Task OnZoomToFitClick() => await Designer.ZoomToFitAsync(); + private async Task OnCenterContentClick() => await Designer.CenterContentAsync(); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesigner.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesigner.cs new file mode 100644 index 0000000..f3aba71 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesigner.cs @@ -0,0 +1,115 @@ +using System.Text.Json.Nodes; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.UI.Contexts; +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.UI.Models; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using MudBlazor; + +namespace Elsa.Studio.Workflows.DiagramDesigners.Flowcharts; + +/// +/// A diagram designer that displays a flowchart. +/// +public class FlowchartDiagramDesigner(ILocalizer localizer) : IDiagramDesignerToolboxProvider +{ + private FlowchartDesignerWrapper? _designerWrapper; + private readonly Guid _id = Guid.NewGuid(); + + /// + public async Task LoadRootActivityAsync(JsonObject activity, IDictionary? activityStatsMap) + { + await InvokeDesignerActionAsync(x => x.LoadFlowchartAsync(activity, activityStatsMap)); + } + + /// + public async Task UpdateActivityAsync(string id, JsonObject activity) + { + await InvokeDesignerActionAsync(x => x.UpdateActivityAsync(id, activity)); + } + + /// + public async Task UpdateActivityStatsAsync(string id, ActivityStats stats) + { + await InvokeDesignerActionAsync(x => x.UpdateActivityStatsAsync(id, stats)); + } + + /// + public async Task SelectActivityAsync(string id) + { + await InvokeDesignerActionAsync(x => x.SelectActivityAsync(id)); + } + + /// + public async Task ReadRootActivityAsync() + { + return await _designerWrapper!.ReadRootActivityAsync(); + } + + /// + public RenderFragment DisplayDesigner(DisplayContext context) + { + var flowchart = context.Activity; + var sequence = 0; + + return builder => + { + builder.OpenComponent(sequence++); + builder.SetKey(_id); + builder.AddAttribute(sequence++, nameof(FlowchartDesignerWrapper.Flowchart), flowchart); + builder.AddAttribute(sequence++, nameof(FlowchartDesignerWrapper.IsReadOnly), context.IsReadOnly); + builder.AddAttribute(sequence++, nameof(FlowchartDesignerWrapper.ActivityStats), context.ActivityStats); + builder.AddAttribute(sequence++, nameof(FlowchartDesignerWrapper.ActivitySelected), context.ActivitySelectedCallback); + builder.AddAttribute(sequence++, nameof(FlowchartDesignerWrapper.ActivityUpdated), context.ActivityUpdated); + builder.AddAttribute(sequence++, nameof(FlowchartDesignerWrapper.ActivityEmbeddedPortSelected), context.ActivityEmbeddedPortSelectedCallback); + builder.AddAttribute(sequence++, nameof(FlowchartDesignerWrapper.ActivityDoubleClick), context.ActivityDoubleClickCallback); + builder.AddAttribute(sequence++, nameof(FlowchartDesignerWrapper.GraphUpdated), context.GraphUpdatedCallback); + builder.AddComponentReferenceCapture(sequence++, @ref => _designerWrapper = (FlowchartDesignerWrapper)@ref); + + builder.CloseComponent(); + }; + } + + /// + public IEnumerable GetToolboxItems(bool isReadonly) + { + yield return DisplayToolboxItem(localizer["Zoom to fit"], Icons.Material.Outlined.FitScreen, localizer["Zoom to fit the screen"], OnZoomToFitClicked); + yield return DisplayToolboxItem(localizer["Center"], Icons.Material.Filled.FilterCenterFocus, localizer["Center"], OnCenterClicked); + + if (!isReadonly) + { + yield return DisplayToolboxItem(localizer["Auto layout"], Icons.Material.Outlined.AutoAwesomeMosaic, localizer["Auto layout"], OnAutoLayoutClicked); + } + } + + private RenderFragment DisplayToolboxItem(string title, string icon, string description, Func onClick) + { + return builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, nameof(MudTooltip.Text), description); + builder.AddAttribute(2, nameof(MudTooltip.ChildContent), (RenderFragment)(childBuilder => + { + childBuilder.OpenComponent(0); + childBuilder.AddAttribute(1, nameof(MudIconButton.Icon), icon); + childBuilder.AddAttribute(2, "title", title); + childBuilder.AddAttribute(3, nameof(MudIconButton.OnClick), EventCallback.Factory.Create(this, onClick)); + childBuilder.CloseComponent(); + })); + + builder.CloseComponent(); + }; + } + + private async Task InvokeDesignerActionAsync(Func action) + { + if (_designerWrapper != null) await action(_designerWrapper); + } + + private Task OnZoomToFitClicked() => _designerWrapper != null ? _designerWrapper.ZoomToFitAsync() : Task.CompletedTask; + private Task OnCenterClicked() => _designerWrapper != null ? _designerWrapper!.CenterContentAsync() : Task.CompletedTask; + private Task OnAutoLayoutClicked() => _designerWrapper != null ? _designerWrapper!.AutoLayoutAsync() : Task.CompletedTask; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesignerProvider.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesignerProvider.cs new file mode 100644 index 0000000..69d1ffd --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesignerProvider.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.UI.Contracts; +using JetBrains.Annotations; + +namespace Elsa.Studio.Workflows.DiagramDesigners.Flowcharts; + +/// +/// A diagram designer provider for the Flowchart designer. +/// +[UsedImplicitly] +public class FlowchartDiagramDesignerProvider(ILocalizer localizer) : IDiagramDesignerProvider +{ + /// + public double Priority => 0; + + /// + public bool GetSupportsActivity(JsonObject activity) => activity.GetTypeName() == "Elsa.Flowchart"; + + /// + public IDiagramDesigner GetEditor() => new FlowchartDiagramDesigner(localizer); +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Elsa.Studio.Workflows.csproj b/src/modules/Elsa.Studio.Workflows/Elsa.Studio.Workflows.csproj new file mode 100644 index 0000000..58b6353 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Elsa.Studio.Workflows.csproj @@ -0,0 +1,25 @@ + + + + Adds workflow management to the studio. + elsa studio module + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/Elsa.Studio.Workflows/Extensions/ActivityExecutionRecordExtensions.cs b/src/modules/Elsa.Studio.Workflows/Extensions/ActivityExecutionRecordExtensions.cs new file mode 100644 index 0000000..79ee9d7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Extensions/ActivityExecutionRecordExtensions.cs @@ -0,0 +1,18 @@ +using Elsa.Api.Client.Resources.ActivityExecutions.Models; + +namespace Elsa.Studio.Workflows.Extensions; + +/// +/// Provides extension methods for . +/// +public static class ActivityExecutionRecordExtensions +{ + /// + /// Determines if the specified activity execution record is fused. + /// + public static bool IsFused(this ActivityExecutionRecord record) + { + // TODO: with blueberry, consider introducing a new property to ActivityExecutionRecord to indicate whether the record has all details or not. + return record.ActivityState != null || record.Outputs != null || record.Exception != null || record.Payload != null || record.Properties.Count > 0; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Extensions/HubConnectionExtensions.cs b/src/modules/Elsa.Studio.Workflows/Extensions/HubConnectionExtensions.cs new file mode 100644 index 0000000..a460bbc --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Extensions/HubConnectionExtensions.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.SignalR.Client; + +namespace Elsa.Studio.Workflows.Extensions +{ + public static class HubConnectionExtensions + { + public static IHubConnectionBuilder WithUrl(this IHubConnectionBuilder builder, string url, IHttpMessageHandlerFactory clientFactory) + { + return builder.WithUrl(url, options => + { + options.HttpMessageHandlerFactory = _ => clientFactory.CreateHandler(); + }); + } + } +} diff --git a/src/modules/Elsa.Studio.Workflows/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Studio.Workflows/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..cc9b7a7 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,54 @@ +using Elsa.Studio.ActivityPortProviders.Extensions; +using Elsa.Studio.Contracts; +using Elsa.Studio.DomInterop.Extensions; +using Elsa.Studio.Extensions; +using Elsa.Studio.UIHints.Extensions; +using Elsa.Studio.Workflows.Contracts; +using Elsa.Studio.Workflows.Designer.Extensions; +using Elsa.Studio.Workflows.DiagramDesigners.Fallback; +using Elsa.Studio.Workflows.DiagramDesigners.Flowcharts; +using Elsa.Studio.Workflows.Handlers; +using Elsa.Studio.Workflows.Menu; +using Elsa.Studio.Workflows.Services; +using Elsa.Studio.Workflows.Widgets; +using Microsoft.Extensions.DependencyInjection; +using MudBlazor.Services; + + +namespace Elsa.Studio.Workflows.Extensions; + +/// +/// Contains extension methods for the interface. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Adds the workflows module. + /// + public static IServiceCollection AddWorkflowsModule(this IServiceCollection services) + { + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddDefaultUIHintHandlers() + .AddDefaultActivityPortProviders() + .AddWorkflowsCore() + .AddWorkflowsDesigner() + .AddDomInterop() + .AddClipboardInterop() + .AddDownloadInterop() + ; + + services + .AddDiagramDesignerProvider() + .AddDiagramDesignerProvider(); + + services.AddNotificationHandler(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Extensions/WorkflowDefinitionExtensions.cs b/src/modules/Elsa.Studio.Workflows/Extensions/WorkflowDefinitionExtensions.cs new file mode 100644 index 0000000..f6d1649 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Extensions/WorkflowDefinitionExtensions.cs @@ -0,0 +1,17 @@ +using Elsa.Api.Client.Resources.WorkflowDefinitions.Models; + +namespace Elsa.Studio.Workflows.Extensions; + +/// Provides extension methods for the WorkflowDefinition class. +public static class WorkflowDefinitionExtensions +{ + /// + /// Determines whether the specified workflow definition is read-only. + /// + /// The workflow definition to check. + /// true if the workflow definition is read-only; otherwise, false. + public static bool GetIsReadOnly(this WorkflowDefinition? workflowDefinition) + { + return workflowDefinition != null && (workflowDefinition.IsLatest == false || (workflowDefinition.Links?.Count(l => l.Rel == "publish") ?? 0) == 0); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Feature.cs b/src/modules/Elsa.Studio.Workflows/Feature.cs new file mode 100644 index 0000000..24befd8 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Feature.cs @@ -0,0 +1,10 @@ +using Elsa.Studio.Abstractions; + +namespace Elsa.Studio.Workflows; + +/// +/// +/// +public class Feature : FeatureBase +{ +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/FodyWeavers.xml b/src/modules/Elsa.Studio.Workflows/FodyWeavers.xml new file mode 100644 index 0000000..00e1d9a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/FodyWeavers.xsd b/src/modules/Elsa.Studio.Workflows/FodyWeavers.xsd new file mode 100644 index 0000000..3f3946e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Handlers/RefreshActivityRegistry.cs b/src/modules/Elsa.Studio.Workflows/Handlers/RefreshActivityRegistry.cs new file mode 100644 index 0000000..3554878 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Handlers/RefreshActivityRegistry.cs @@ -0,0 +1,40 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Notifications; +using JetBrains.Annotations; + +namespace Elsa.Studio.Workflows.Handlers; + +/// A handler that refreshes the activity registry when a workflow definition is deleted, published or retracted. +[UsedImplicitly] +public class RefreshActivityRegistry : INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler +{ + private readonly IActivityRegistry _activityRegistry; + + /// + /// Initializes a new instance of the class. + /// + public RefreshActivityRegistry(IActivityRegistry activityRegistry) + { + _activityRegistry = activityRegistry; + } + + async Task INotificationHandler.HandleAsync(WorkflowDefinitionDeleted notification, CancellationToken cancellationToken) => await RefreshActivityRegistryAsync(cancellationToken); + async Task INotificationHandler.HandleAsync(WorkflowDefinitionPublished notification, CancellationToken cancellationToken) => await RefreshActivityRegistryAsync(cancellationToken); + async Task INotificationHandler.HandleAsync(WorkflowDefinitionRetracted notification, CancellationToken cancellationToken) => await RefreshActivityRegistryAsync(cancellationToken); + async Task INotificationHandler.HandleAsync(BulkWorkflowDefinitionsDeleted notification, CancellationToken cancellationToken) => await RefreshActivityRegistryAsync(cancellationToken); + async Task INotificationHandler.HandleAsync(BulkWorkflowDefinitionVersionsDeleted notification, CancellationToken cancellationToken) => await RefreshActivityRegistryAsync(cancellationToken); + async Task INotificationHandler.HandleAsync(BulkWorkflowDefinitionsPublished notification, CancellationToken cancellationToken) => await RefreshActivityRegistryAsync(cancellationToken); + async Task INotificationHandler.HandleAsync(BulkWorkflowDefinitionsRetracted notification, CancellationToken cancellationToken) => await RefreshActivityRegistryAsync(cancellationToken); + + private async Task RefreshActivityRegistryAsync(CancellationToken cancellationToken = default) + { + await _activityRegistry.RefreshAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Menu/WorkflowsMenu.cs b/src/modules/Elsa.Studio.Workflows/Menu/WorkflowsMenu.cs new file mode 100644 index 0000000..1813405 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Menu/WorkflowsMenu.cs @@ -0,0 +1,38 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.Models; +using Elsa.Studio.Workflows.Services; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Menu; + +public class WorkflowsMenu(ILocalizer localizer) : IMenuProvider +{ + public ValueTask> GetMenuItemsAsync(CancellationToken cancellationToken = default) + { + var menuItems = new List + { + new() + { + Icon = Icons.Material.Outlined.Schema, + Text = localizer["Workflows"], + GroupName = MenuItemGroups.General.Name, + SubMenuItems = + { + new MenuItem() + { + Text = localizer["Definitions"], + Href = "workflows/definitions" + }, + new MenuItem() + { + Text = localizer["Instances"], + Href = "workflows/instances" + }, + } + } + }; + + return new ValueTask>(menuItems); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Models/DragDropManager.cs b/src/modules/Elsa.Studio.Workflows/Models/DragDropManager.cs new file mode 100644 index 0000000..68bce79 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Models/DragDropManager.cs @@ -0,0 +1,12 @@ +namespace Elsa.Studio.Workflows.Models; + +/// +/// A manager for drag and drop operations. +/// +public class DragDropManager +{ + /// + /// A payload value associated with the element being dragged. + /// + public object? Payload { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Models/PagedResult.cs b/src/modules/Elsa.Studio.Workflows/Models/PagedResult.cs new file mode 100644 index 0000000..1f9c616 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Models/PagedResult.cs @@ -0,0 +1,3 @@ +namespace Elsa.Studio.Workflows.Models; + +public record PagedResult(ICollection Items, long TotalCount); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Models/WorkflowInstanceObserverContext.cs b/src/modules/Elsa.Studio.Workflows/Models/WorkflowInstanceObserverContext.cs new file mode 100644 index 0000000..f9c9e16 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Models/WorkflowInstanceObserverContext.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Workflows.Models; + +public class WorkflowInstanceObserverContext +{ + public string WorkflowInstanceId { get; set; } = default!; + public JsonObject? ContainerActivity { get; set; } + public CancellationToken CancellationToken { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Models/WorkflowMetadataModel.cs b/src/modules/Elsa.Studio.Workflows/Models/WorkflowMetadataModel.cs new file mode 100644 index 0000000..ae9f898 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Models/WorkflowMetadataModel.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations; + +namespace Elsa.Studio.Workflows.Models; + +/// +/// Represents the metadata of a workflow. +/// +public class WorkflowMetadataModel +{ + /// + /// Gets or sets the ID of the workflow definition. + /// + public string? DefinitionId { get; set; } + + /// + /// Gets or sets the name of the workflow. + /// + [Required] public string? Name { get; set; } + + /// + /// Gets or sets the description of the workflow. + /// + public string? Description { get; set; } = default!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Pages/WorkflowDefinitions/Edit/Index.razor b/src/modules/Elsa.Studio.Workflows/Pages/WorkflowDefinitions/Edit/Index.razor new file mode 100644 index 0000000..d46c3fe --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Pages/WorkflowDefinitions/Edit/Index.razor @@ -0,0 +1,18 @@ +@page "/workflows/definitions/{definitionId}/edit" +@using Microsoft.Extensions.Localization +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +@Localizer["Workflow definitions Editor"] + + + +@code +{ + /// + /// The ID of the workflow definition to edit. + /// + [Parameter] + public string DefinitionId { get; set; } = default!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Pages/WorkflowDefinitions/List/Index.razor b/src/modules/Elsa.Studio.Workflows/Pages/WorkflowDefinitions/List/Index.razor new file mode 100644 index 0000000..f79e2cc --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Pages/WorkflowDefinitions/List/Index.razor @@ -0,0 +1,17 @@ +@page "/workflows/definitions" +@inherits StudioComponentBase +@using Elsa.Studio.Workflows.Services +@inject ILocalizer Localizer + +@Localizer["Workflow definitions Editor"] + + +@code { + + [Inject] NavigationManager NavigationManager { get; set; } = default!; + + private void OnWorkflowDefinitionEdit(string definitionId) + { + NavigationManager.NavigateTo($"workflows/definitions/{definitionId}/edit"); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Pages/WorkflowInstances/List/Index.razor b/src/modules/Elsa.Studio.Workflows/Pages/WorkflowInstances/List/Index.razor new file mode 100644 index 0000000..c91e9e6 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Pages/WorkflowInstances/List/Index.razor @@ -0,0 +1,16 @@ +@page "/workflows/instances" +@inherits StudioComponentBase + +Workflow instances + + +@code { + + [Inject] NavigationManager NavigationManager { get; set; } = default!; + + private void OnViewWorkflowInstance(string instanceId) + { + NavigationManager.NavigateTo($"workflows/instances/{instanceId}/view"); + } + +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Pages/WorkflowInstances/View/Index.razor b/src/modules/Elsa.Studio.Workflows/Pages/WorkflowInstances/View/Index.razor new file mode 100644 index 0000000..9c497f0 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Pages/WorkflowInstances/View/Index.razor @@ -0,0 +1,13 @@ +@page "/workflows/instances/{id}/view" +@inherits StudioComponentBase + +Workflow instance + + +@code +{ + /// + /// The ID of the workflow instance to view. + /// + [Parameter] public string Id { get; set; } = default!; +} diff --git a/src/modules/Elsa.Studio.Workflows/Services/DisconnectedWorkflowInstanceObserver.cs b/src/modules/Elsa.Studio.Workflows/Services/DisconnectedWorkflowInstanceObserver.cs new file mode 100644 index 0000000..a5dfbf4 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Services/DisconnectedWorkflowInstanceObserver.cs @@ -0,0 +1,20 @@ +using Elsa.Api.Client.RealTime.Messages; +using Elsa.Studio.Workflows.Contracts; + +namespace Elsa.Studio.Workflows.Services; + +/// An implementation of that does nothing. +public class DisconnectedWorkflowInstanceObserver : IWorkflowInstanceObserver +{ + public string? Name { get; set; } + + /// + public event Func WorkflowJournalUpdated = default!; + + /// + public event Func ActivityExecutionLogUpdated = default!; + + /// + public event Func WorkflowInstanceUpdated = default!; + ValueTask IAsyncDisposable.DisposeAsync() => ValueTask.CompletedTask; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Services/PollingWorkflowInstanceObserver.cs b/src/modules/Elsa.Studio.Workflows/Services/PollingWorkflowInstanceObserver.cs new file mode 100644 index 0000000..8a0aad8 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Services/PollingWorkflowInstanceObserver.cs @@ -0,0 +1,102 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.RealTime.Messages; +using Elsa.Api.Client.Resources.ActivityExecutions.Contracts; +using Elsa.Api.Client.Resources.ActivityExecutions.Models; +using Elsa.Api.Client.Resources.ActivityExecutions.Requests; +using Elsa.Api.Client.Resources.WorkflowInstances.Contracts; +using Elsa.Api.Client.Resources.WorkflowInstances.Enums; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Contracts; +using Elsa.Studio.Workflows.Models; + +namespace Elsa.Studio.Workflows.Services; + +/// Observes a workflow instance by periodically polling for updates and raising corresponding events. +public class PollingWorkflowInstanceObserver : IWorkflowInstanceObserver +{ + private readonly IWorkflowInstancesApi _workflowInstancesApi; + private readonly IActivityExecutionsApi _activityExecutionsApi; + private readonly string _workflowInstanceId; + private readonly JsonObject? _containerActivity; + private readonly TimeSpan _pollingInterval = TimeSpan.FromSeconds(5); + private DateTimeOffset _lastUpdateAt = DateTimeOffset.MinValue; + private bool _checkForUpdates = true; + + /// Observes a workflow instance by periodically polling for updates and raising corresponding events. + public PollingWorkflowInstanceObserver( + WorkflowInstanceObserverContext context, + IWorkflowInstancesApi workflowInstancesApi, + IActivityExecutionsApi activityExecutionsApi) + { + _workflowInstancesApi = workflowInstancesApi; + _activityExecutionsApi = activityExecutionsApi; + _workflowInstanceId = context.WorkflowInstanceId; + _containerActivity = context.ContainerActivity; + + _ = Task.Run(GetRecentExecutionRecordsAsync); + } + + /// + public event Func WorkflowJournalUpdated = default!; + + /// + public event Func ActivityExecutionLogUpdated = default!; + + /// + public event Func WorkflowInstanceUpdated = default!; + + private async Task GetRecentExecutionRecordsAsync() + { + while (_checkForUpdates) + { + try + { + var response = await _workflowInstancesApi.GetExecutionStateAsync(_workflowInstanceId); + var lastUpdateAt = response.UpdatedAt; + + if (_lastUpdateAt < lastUpdateAt) + { + _lastUpdateAt = lastUpdateAt; + if (WorkflowJournalUpdated != null!) await WorkflowJournalUpdated(new WorkflowExecutionLogUpdatedMessage()); + if (ActivityExecutionLogUpdated != null && _containerActivity != null) + { + var activityExecutionStats = await GetActivityExecutionStatsAsync(_containerActivity); + await ActivityExecutionLogUpdated(new ActivityExecutionLogUpdatedMessage(activityExecutionStats)); + } + + if (WorkflowInstanceUpdated != null!) await WorkflowInstanceUpdated(new WorkflowInstanceUpdatedMessage(_workflowInstanceId)); + } + + if (response.Status == WorkflowStatus.Finished) + _checkForUpdates = false; + } + catch (ObjectDisposedException) + { + _checkForUpdates = false; + break; + } + + await Task.Delay(_pollingInterval); + } + } + + private async Task> GetActivityExecutionStatsAsync(JsonObject container) + { + var activityNodeIds = container.GetActivities().Select(x => x.GetNodeId()).ToList(); + var request = new GetActivityExecutionReportRequest + { + WorkflowInstanceId = _workflowInstanceId, + ActivityNodeIds = activityNodeIds, + }; + var report = await _activityExecutionsApi.GetReportAsync(request); + return report.Stats; + } + + /// + public ValueTask DisposeAsync() + { + _checkForUpdates = false; + return ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Services/SignalRWorkflowInstanceObserver.cs b/src/modules/Elsa.Studio.Workflows/Services/SignalRWorkflowInstanceObserver.cs new file mode 100644 index 0000000..5ac109a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Services/SignalRWorkflowInstanceObserver.cs @@ -0,0 +1,51 @@ +using Elsa.Api.Client.RealTime.Messages; +using Elsa.Studio.Workflows.Contracts; +using Microsoft.AspNetCore.SignalR.Client; + +namespace Elsa.Studio.Workflows.Services; + +/// A wrapper around a SignalR connection that receives notifications about workflow instance updates. +public class SignalRWorkflowInstanceObserver : IWorkflowInstanceObserver +{ + private readonly HubConnection _connection; + + /// A wrapper around a SignalR connection that receives notifications about workflow instance updates. + public SignalRWorkflowInstanceObserver(HubConnection connection) + { + _connection = connection; + + connection.On("ActivityExecutionLogUpdatedAsync", async (ActivityExecutionLogUpdatedMessage message) => await OnActivityExecutionLogUpdatedAsync(message)); + connection.On("WorkflowExecutionLogUpdatedAsync", async (WorkflowExecutionLogUpdatedMessage message) => await OnWorkflowJournalUpdatedAsync(message)); + connection.On("WorkflowInstanceUpdatedAsync", async (WorkflowInstanceUpdatedMessage message) => await OnWorkflowInstanceUpdatedAsync(message)); + } + + /// + public event Func WorkflowJournalUpdated = default!; + + /// + public event Func ActivityExecutionLogUpdated = default!; + + /// + public event Func WorkflowInstanceUpdated = default!; + + private async Task OnWorkflowJournalUpdatedAsync(WorkflowExecutionLogUpdatedMessage arg) + { + if (WorkflowJournalUpdated != null!) await WorkflowJournalUpdated(arg); + } + + private async Task OnActivityExecutionLogUpdatedAsync(ActivityExecutionLogUpdatedMessage arg) + { + if (ActivityExecutionLogUpdated != null!) await ActivityExecutionLogUpdated(arg); + } + + private async Task OnWorkflowInstanceUpdatedAsync(WorkflowInstanceUpdatedMessage arg) + { + if (WorkflowInstanceUpdated != null!) await WorkflowInstanceUpdated(arg); + } + + async ValueTask IAsyncDisposable.DisposeAsync() + { + await _connection.StopAsync(); + await _connection.DisposeAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Services/WorkflowInstanceObserverFactory.cs b/src/modules/Elsa.Studio.Workflows/Services/WorkflowInstanceObserverFactory.cs new file mode 100644 index 0000000..4f0c49e --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Services/WorkflowInstanceObserverFactory.cs @@ -0,0 +1,74 @@ +using System.Net; +using Elsa.Api.Client.Resources.ActivityExecutions.Contracts; +using Elsa.Api.Client.Resources.WorkflowInstances.Contracts; +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Contracts; +using Elsa.Studio.Workflows.Extensions; +using Elsa.Studio.Workflows.Models; +using Microsoft.AspNetCore.SignalR.Client; +using Microsoft.Extensions.Logging; + +namespace Elsa.Studio.Workflows.Services; + +/// +public class WorkflowInstanceObserverFactory( + IBackendApiClientProvider backendApiClientProvider, + IRemoteFeatureProvider remoteFeatureProvider, + IHttpMessageHandlerFactory httpMessageHandlerFactory, + ILogger logger) : IWorkflowInstanceObserverFactory +{ + /// + public Task CreateAsync(string workflowInstanceId) + { + var context = new WorkflowInstanceObserverContext + { + WorkflowInstanceId = workflowInstanceId + }; + + return CreateAsync(context); + } + + /// + public async Task CreateAsync(WorkflowInstanceObserverContext context) + { + var cancellationToken = context.CancellationToken; + var workflowInstancesApi = await backendApiClientProvider.GetApiAsync(cancellationToken); + var activityExecutionsApi = await backendApiClientProvider.GetApiAsync(cancellationToken); + var workflowInstanceId = context.WorkflowInstanceId; + + // Only establish a SignalR connection if that feature is enabled. + if (!await remoteFeatureProvider.IsEnabledAsync("Elsa.RealTimeWorkflowUpdates", cancellationToken)) + { + // Fall back to regular polling. + return new PollingWorkflowInstanceObserver( + context, + workflowInstancesApi, + activityExecutionsApi); + } + + // Set-up the SignalR connection. + var baseUrl = backendApiClientProvider.Url; + var hubUrl = new Uri(baseUrl, "hubs/workflow-instance").ToString(); + var connection = new HubConnectionBuilder() + .WithUrl(hubUrl, httpMessageHandlerFactory) + .Build(); + + var observer = new SignalRWorkflowInstanceObserver(connection); + + try + { + await connection.StartAsync(cancellationToken); + } + catch (HttpRequestException e) when (e.StatusCode == HttpStatusCode.NotFound) + { + logger.LogWarning("The workflow instance observer hub was not found, but the RealTimeWorkflows feature was enabled. Please make sure to call `app.UseWorkflowsSignalRHubs()` from the workflow server to install the required SignalR middleware component. Falling back to polling observer"); + return new PollingWorkflowInstanceObserver( + context, + workflowInstancesApi, + activityExecutionsApi); + } + + await connection.SendAsync("ObserveInstanceAsync", workflowInstanceId, cancellationToken: cancellationToken); + return observer; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Shared/Args/DesignerPathChangedArgs.cs b/src/modules/Elsa.Studio.Workflows/Shared/Args/DesignerPathChangedArgs.cs new file mode 100644 index 0000000..9ded831 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Shared/Args/DesignerPathChangedArgs.cs @@ -0,0 +1,6 @@ +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Workflows.Shared.Args; + +/// Represents the event arguments when the designer path changes. +public record DesignerPathChangedArgs(JsonObject ParentActivity, JsonObject ContainerActivity); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor b/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor new file mode 100644 index 0000000..5545b2f --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor @@ -0,0 +1,38 @@ +@using Elsa.Studio.Workflows.UI.Contracts +@inherits StudioComponentBase + + + @{ + if (_diagramDesigner is IDiagramDesignerToolboxProvider toolboxProvider) + { + foreach (var toolboxComponent in toolboxProvider.GetToolboxItems(IsReadOnly)) + { + @toolboxComponent + } + } + } + + @CustomToolbarItems + + + +
+ + + + @if (context.Icon != null) + { + + } + @context.Text + + + + +
+ +
+
+
+
+@DisplayDesigner() \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs new file mode 100644 index 0000000..3ecb19a --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs @@ -0,0 +1,539 @@ +using System.Text.Json.Nodes; +using Elsa.Api.Client.Extensions; +using Elsa.Api.Client.Shared.Models; +using Elsa.Studio.Workflows.Domain.Contexts; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Domain.Extensions; +using Elsa.Studio.Workflows.Domain.Models; +using Elsa.Studio.Workflows.Extensions; +using Elsa.Studio.Workflows.Models; +using Elsa.Studio.Workflows.Shared.Args; +using Elsa.Studio.Workflows.UI.Args; +using Elsa.Studio.Workflows.UI.Contexts; +using Elsa.Studio.Workflows.UI.Contracts; +using Elsa.Studio.Workflows.UI.Models; +using Humanizer; +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Elsa.Studio.Workflows.Shared.Components; + +/// A wrapper around the diagram designer that provides a breadcrumb and a toolbar. +public partial class DiagramDesignerWrapper +{ + private IDiagramDesigner? _diagramDesigner; + private Stack _pathSegments = new(); + private JsonObject? _currentContainerActivity; + private List _breadcrumbItems = new(); + private IDictionary _activityStats = new Dictionary(); + private ActivityGraph _activityGraph = null!; + private IDictionary _indexedActivityNodes = new Dictionary(); + + /// The workflow definition version ID. + [Parameter] public string WorkflowDefinitionVersionId { get; set; } = null!; + + /// The root activity to display. + [Parameter] public JsonObject Activity { get; set; } = null!; + + /// Whether the designer is read-only. + [Parameter] public bool IsReadOnly { get; set; } + + /// The workflow instance ID, if any. + [Parameter] public string? WorkflowInstanceId { get; set; } + + /// A custom toolbar to display. + [Parameter] public RenderFragment? CustomToolbarItems { get; set; } + + /// Whether the designer is progressing. + [Parameter] public bool IsProgressing { get; set; } + + /// An event raised when an activity is selected. + [Parameter] public EventCallback ActivitySelected { get; set; } + + /// An event raised when an embedded port is selected. + [Parameter] public EventCallback GraphUpdated { get; set; } + + [Parameter] public EventCallback ActivityUpdated { get; set; } + + /// An event raised when the path changes. + [Parameter] public EventCallback PathChanged { get; set; } + + [Inject] private IDiagramDesignerService DiagramDesignerService { get; set; } = null!; + [Inject] private IActivityDisplaySettingsRegistry ActivityDisplaySettingsRegistry { get; set; } = null!; + [Inject] private IActivityPortService ActivityPortService { get; set; } = null!; + [Inject] private IActivityRegistry ActivityRegistry { get; set; } = null!; + [Inject] private IIdentityGenerator IdentityGenerator { get; set; } = null!; + [Inject] private IActivityExecutionService ActivityExecutionService { get; set; } = null!; + [Inject] private IActivityVisitor ActivityVisitor { get; set; } = null!; + [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = null!; + [Inject] private ISnackbar Snackbar { get; set; } = null!; + + private ActivityPathSegment? CurrentPathSegment => _pathSegments.TryPeek(out var segment) ? segment : null; + + /// Selects the activity with the specified ID. + /// The ID of the activity ID select. + public async Task SelectActivityByActivityIdAsync(string activityId) + { + var containerActivity = GetCurrentContainerActivity(); + var activities = containerActivity.GetActivities(); + var activityToSelect = activities.FirstOrDefault(x => x.GetId() == activityId); + + await SelectActivityAsync(activityToSelect); + } + + /// Selects the activity with the specified node ID. + /// The ID of the activity node to select. + public async Task SelectActivityAsync(string nodeId) + { + var containerActivity = GetCurrentContainerActivityOrRoot(); + var activities = containerActivity.GetActivities(); + var activityToSelect = activities.FirstOrDefault(x => x.GetNodeId() == nodeId); + + await SelectActivityAsync(activityToSelect, nodeId); + } + + private async Task SelectActivityAsync(JsonObject? activityToSelect, string? nodeId = null) + { + if (activityToSelect != null) + { + await _diagramDesigner!.SelectActivityAsync(activityToSelect.GetId()); + return; + } + + if (nodeId == null) + return; + + // Load the selected node path from the backend. + var pathSegmentsResponse = await WorkflowDefinitionService.GetPathSegmentsAsync(WorkflowDefinitionVersionId, nodeId); + + if (pathSegmentsResponse == null) + return; + + await IndexActivityNodes(pathSegmentsResponse.Container.Activity); + + activityToSelect = pathSegmentsResponse.ChildNode.Activity; + var pathSegments = pathSegmentsResponse.PathSegments.ToList(); + StateHasChanged(); + + // Reassign the current path. + await UpdatePathSegmentsAsync(segments => + { + segments.Clear(); + + foreach (var segment in pathSegments) + segments.Push(segment); + }); + + // Display the new segment. + _currentContainerActivity = null; + await DisplayCurrentSegmentAsync(); + + // Select the activity. + await _diagramDesigner!.SelectActivityAsync(activityToSelect.GetId()); + } + + /// Updates the stats of the specified activity. + /// The ID of the activity to update. + /// The stats to update. + public async Task UpdateActivityStatsAsync(string activityId, ActivityStats stats) + { + await _diagramDesigner!.UpdateActivityStatsAsync(activityId, stats); + } + + /// Reads the activity from the designer. + public async Task ReadActivityAsync() + { + return await _diagramDesigner!.ReadRootActivityAsync(); + } + + /// Gets the root activity graph. + public Task GetActivityGraphAsync() + { + return Task.FromResult(_activityGraph); + } + + /// Gets the root activity. + public Task GetActivityAsync() + { + var rootActivity = _activityGraph.Activity; + return Task.FromResult(rootActivity); + } + + /// Loads the specified activity into the designer. + /// The activity to load. + public async Task LoadActivityAsync(JsonObject activity) + { + Activity = activity; + _diagramDesigner = DiagramDesignerService.GetDiagramDesigner(activity); + _activityGraph = await ActivityVisitor.VisitAndCreateGraphAsync(activity); + await IndexActivityNodes(_activityGraph.Activity); + await UpdatePathSegmentsAsync(segments => segments.Clear()); + await UpdateBreadcrumbItemsAsync(); + StateHasChanged(); + } + + /// Updates the specified activity in the designer. + /// The ID of the activity to update. + /// The activity to update. + public async Task UpdateActivityAsync(string activityId, JsonObject activity) + { + var currentContainer = GetCurrentContainerActivityOrRoot(); + + if (currentContainer == activity) + { + if (GraphUpdated.HasDelegate) + await GraphUpdated.InvokeAsync(); + + return; + } + + await _diagramDesigner!.UpdateActivityAsync(activityId, activity); + } + + /// The current container activity or the root activity of the graph. + public JsonObject GetCurrentContainerActivityOrRoot() + { + var activity = GetCurrentContainerActivity(); + return _currentContainerActivity = activity ?? Activity; + } + + private async Task GetCurrentContainerActivityOrRootAsync() + { + var activity = GetCurrentContainerActivity(); + + if (activity == null) + { + var lastSegment = _pathSegments.First(); + var parentNodeId = lastSegment.ActivityNodeId; + var selectedActivityGraph = await WorkflowDefinitionService.FindSubgraphAsync(WorkflowDefinitionVersionId, parentNodeId); + var propName = lastSegment.PortName.Camelize(); + var selectedPortActivity = (JsonObject?)selectedActivityGraph!.Activity[propName]; + activity = selectedPortActivity; + _currentContainerActivity = activity; + await IndexActivityNodes(selectedActivityGraph.Activity); + } + + return activity ?? Activity; + } + + private async Task IndexActivityNodes(JsonObject activity) + { + var visitedNode = await ActivityVisitor.VisitAsync(activity); + var nodes = visitedNode.Flatten(); + foreach (var node in nodes) _indexedActivityNodes[node.NodeId] = node; + } + + private JsonObject? GetCurrentContainerActivity() + { + if (_currentContainerActivity != null) + return _currentContainerActivity; + + var lastSegment = _pathSegments.FirstOrDefault(); + + if (lastSegment == null) + { + _currentContainerActivity = Activity; + return _currentContainerActivity; + } + + var nodeId = lastSegment.ActivityNodeId; + var node = _indexedActivityNodes.TryGetValue(nodeId, out var activityNode) ? activityNode : null; + + if (node is null) + return null; + + var activity = node.Activity; + var port = lastSegment.PortName; + var embeddedActivity = GetEmbeddedActivity(activity, port); + + if (embeddedActivity?.GetTypeName() == "Elsa.Workflow") + embeddedActivity = embeddedActivity.GetRoot(); + + return embeddedActivity ?? Activity; + } + + /// The parent activity of the current activity being loaded in the designer. + public JsonObject GetParentActivity() + { + var lastSegment = _pathSegments.FirstOrDefault(); + var nodeId = lastSegment?.ActivityNodeId; + var node = nodeId != null ? _indexedActivityNodes.TryGetValue(nodeId, out var activityNode) ? activityNode : null : null; + return node?.Activity ?? Activity; + } + + /// + protected override async Task OnInitializedAsync() + { + await ActivityRegistry.EnsureLoadedAsync(); + await LoadActivityAsync(Activity); + } + + /// Updates the current path. + /// A delegate that manipulates the path + private async Task UpdatePathSegmentsAsync(Action> action) + { + action(_pathSegments); + _currentContainerActivity = null; + + if (PathChanged.HasDelegate) + { + var parentActivity = GetParentActivity(); + var currentContainerActivity = GetCurrentContainerActivityOrRoot(); + await PathChanged.InvokeAsync(new(parentActivity, currentContainerActivity)); + } + } + + private JsonObject? GetEmbeddedActivity(JsonObject activity, string portName) + { + var activityTypeName = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var activityDescriptor = ActivityRegistry.Find(activityTypeName, activityVersion)!; + var portProviderContext = new PortProviderContext(activityDescriptor, activity); + var portProvider = ActivityPortService.GetProvider(portProviderContext); + var activityInPort = portProvider.ResolvePort(portName, portProviderContext); + + return activityInPort; + } + + private async Task UpdateBreadcrumbItemsAsync() + { + _breadcrumbItems = (await GetBreadcrumbItems()).ToList(); + await RefreshActivityStatsAsync(); + StateHasChanged(); + } + + private async Task RefreshActivityStatsAsync() + { + if (WorkflowInstanceId != null) + { + var currentContainerActivity = GetCurrentContainerActivityOrRoot(); + var report = await ActivityExecutionService.GetReportAsync(WorkflowInstanceId, currentContainerActivity); + _activityStats = report.Stats.ToDictionary(x => x.ActivityNodeId, x => new ActivityStats + { + Faulted = x.IsFaulted, + Blocked = x.IsBlocked, + Completed = x.CompletedCount, + Started = x.StartedCount, + Uncompleted = x.UncompletedCount, + Metadata = x.Metadata + }); + } + } + + private async Task> GetBreadcrumbItems() + { + var breadcrumbItems = new List(); + + if (_pathSegments.Any()) + breadcrumbItems.Add(new("Root", "#_root_", false, Icons.Material.Outlined.Home)); + + var nodeLookup = _indexedActivityNodes; + var firstSegment = _pathSegments.FirstOrDefault(); + + foreach (var segment in _pathSegments.Reverse()) + { + var activityNodeId = segment.ActivityNodeId; + + if (!nodeLookup.TryGetValue(activityNodeId, out var activityNode)) + { + activityNode = await WorkflowDefinitionService.FindSubgraphAsync(WorkflowDefinitionVersionId, activityNodeId); + } + + if (activityNode == null) + continue; + + var activity = activityNode.Activity; + var activityTypeName = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var activityDescriptor = ActivityRegistry.Find(activityTypeName, activityVersion)!; + var portProviderContext = new PortProviderContext(activityDescriptor, activity); + var portProvider = ActivityPortService.GetProvider(portProviderContext); + var ports = portProvider.GetPorts(portProviderContext); + var embeddedPort = ports.First(x => x.Name == segment.PortName); + var displaySettings = ActivityDisplaySettingsRegistry.GetSettings(activityTypeName); + var disabled = segment == firstSegment; + var activityDisplayText = activity.GetName() ?? activityDescriptor.DisplayName; + var breadcrumbDisplayText = $"{activityDisplayText}: {embeddedPort.DisplayName}"; + var activityBreadcrumbItem = new BreadcrumbItem(breadcrumbDisplayText, $"#{activity.GetId()}", disabled, displaySettings.Icon); + + breadcrumbItems.Add(activityBreadcrumbItem); + } + + return breadcrumbItems; + } + + private async Task DisplayCurrentSegmentAsync() + { + var currentContainerActivity = await GetCurrentContainerActivityOrRootAsync(); + + if (_diagramDesigner == null) + return; + + await _diagramDesigner.LoadRootActivityAsync(currentContainerActivity, _activityStats); + await UpdateBreadcrumbItemsAsync(); + } + + private RenderFragment? DisplayDesigner() + { + return _diagramDesigner?.DisplayDesigner(new( + GetCurrentContainerActivityOrRoot(), + ActivitySelected, + EventCallback.Factory.Create(this, OnActivityUpdated), + EventCallback.Factory.Create(this, OnActivityEmbeddedPortSelected), + EventCallback.Factory.Create(this, OnActivityDoubleClick), + EventCallback.Factory.Create(this, OnGraphUpdated), + IsReadOnly, + _activityStats)); + } + + private async Task OnActivityDoubleClick(JsonObject activity) + { + if (!IsReadOnly) + return; + + // If the activity is a workflow definition activity, then open the workflow definition editor. + if (activity.GetWorkflowDefinitionId() != null) + { + await OnActivityEmbeddedPortSelected(new(activity, "Root")); + } + } + + private async Task OnActivityUpdated(JsonObject activity) + { + if (ActivityUpdated.HasDelegate) + await ActivityUpdated.InvokeAsync(activity); + } + + private async Task OnActivityEmbeddedPortSelected(ActivityEmbeddedPortSelectedArgs args) + { + var nodes = _indexedActivityNodes; + var selectedActivity = args.Activity; + var activity = nodes.TryGetValue(selectedActivity.GetNodeId(), out var selectedActivityNode) ? selectedActivityNode.Activity : null; + + if (activity is null) + return; + + var portName = args.PortName; + var activityTypeName = activity.GetTypeName(); + var activityVersion = activity.GetVersion(); + var activityDescriptor = ActivityRegistry.Find(activityTypeName, activityVersion)!; + var portProviderContext = new PortProviderContext(activityDescriptor, activity); + var portProvider = ActivityPortService.GetProvider(portProviderContext); + var embeddedActivity = portProvider.ResolvePort(portName, portProviderContext); + + if (embeddedActivity == null) + { + // Lazy load. + if (activityDescriptor.CustomProperties.ContainsKey("WorkflowDefinitionVersionId")) + { + var parentNodeId = activity.GetNodeId(); + var selectedActivityGraph = await WorkflowDefinitionService.FindSubgraphAsync(WorkflowDefinitionVersionId, parentNodeId) ?? throw new InvalidOperationException($"Could not find selected activity graph for {parentNodeId}"); + var propName = portName.Camelize(); + var selectedPortActivity = (JsonObject)selectedActivityGraph.Activity[propName]!; + embeddedActivity = selectedPortActivity; + portProvider.AssignPort(args.PortName, embeddedActivity, new(activityDescriptor, activity)); + await IndexActivityNodes(selectedActivityGraph.Activity); + } + } + + if (embeddedActivity != null) + { + var embeddedActivityTypeName = embeddedActivity.GetTypeName(); + + // If the embedded activity has no designer support, then open it in the activity properties editor by raising the ActivitySelected event. + if (embeddedActivityTypeName != "Elsa.Flowchart" && embeddedActivityTypeName != "Elsa.Workflow") + { + if (ActivitySelected.HasDelegate) + await ActivitySelected.InvokeAsync(embeddedActivity); + return; + } + + // If the embedded activity type is a flowchart or workflow, we can display it in the designer. + } + else + { + if (!IsReadOnly) + { + var embeddedActivityId = IdentityGenerator.GenerateId(); + // Create a flowchart and embed it into the activity. + embeddedActivity = new(new Dictionary + { + ["id"] = embeddedActivityId, + ["nodeId"] = $"{activity.GetNodeId()}:{embeddedActivityId}", + ["type"] = "Elsa.Flowchart", + ["version"] = 1, + ["name"] = "Flowchart1", + }); + + portProvider.AssignPort(args.PortName, embeddedActivity, new(activityDescriptor, activity)); + + // Update the graph in the designer. + await _diagramDesigner!.UpdateActivityAsync(activity.GetId(), activity); + } + else + { + return; + } + } + + // Create a new path segment of the container activity and push it onto the stack. + var segment = new ActivityPathSegment(activity.GetNodeId(), activity.GetId(), activity.GetTypeName(), args.PortName); + + await UpdatePathSegmentsAsync(segments => segments.Push(segment)); + await DisplayCurrentSegmentAsync(); + } + + private async Task OnGraphUpdated() + { + var embeddedActivity = await _diagramDesigner!.ReadRootActivityAsync(); + var currentSegment = CurrentPathSegment; + + if (currentSegment == null) // Root activity was updated. + { + _activityGraph = await ActivityVisitor.VisitAndCreateGraphAsync(embeddedActivity); + await IndexActivityNodes(_activityGraph.Activity); + } + else + { + var currentActivityNode = _activityGraph.ActivityNodeLookup[currentSegment.ActivityNodeId]; + var currentActivity = currentActivityNode.Activity; + var portName = currentSegment.PortName; + var activityTypeName = currentActivity.GetTypeName(); + var activityVersion = currentActivity.GetVersion(); + var activityDescriptor = ActivityRegistry.Find(activityTypeName, activityVersion)!; + var portProviderContext = new PortProviderContext(activityDescriptor, currentActivity); + var portProvider = ActivityPortService.GetProvider(portProviderContext); + + portProvider.AssignPort(portName, embeddedActivity, portProviderContext); + await _activityGraph.IndexAsync(); + await IndexActivityNodes(_activityGraph.Activity); + } + + if (GraphUpdated.HasDelegate) + await GraphUpdated.InvokeAsync(); + } + + private async Task OnBreadcrumbItemClicked(BreadcrumbItem item) + { + if (item.Href == "#_root_") + { + await UpdatePathSegmentsAsync(segments => segments.Clear()); + await DisplayCurrentSegmentAsync(); + return; + } + + var activityId = item.Href![1..]; + + await UpdatePathSegmentsAsync(segments => + { + while (segments.TryPeek(out var segment)) + if (segment.ActivityId == activityId) + break; + else + segments.Pop(); + }); + + _currentContainerActivity = null; + await DisplayCurrentSegmentAsync(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Shared/Components/GraphSegment.cs b/src/modules/Elsa.Studio.Workflows/Shared/Components/GraphSegment.cs new file mode 100644 index 0000000..86bdba1 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Shared/Components/GraphSegment.cs @@ -0,0 +1,5 @@ +using System.Text.Json.Nodes; + +namespace Elsa.Studio.Workflows.Shared.Components; + +public record GraphSegment(JsonObject Activity, string PortName, JsonObject? EmbeddedActivity = default); \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Validators/WorkflowPropertiesModelValidator.cs b/src/modules/Elsa.Studio.Workflows/Validators/WorkflowPropertiesModelValidator.cs new file mode 100644 index 0000000..2cc1940 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Validators/WorkflowPropertiesModelValidator.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Localization; +using Elsa.Studio.Workflows.Domain.Contracts; +using Elsa.Studio.Workflows.Models; +using FluentValidation; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Localization; + +namespace Elsa.Studio.Workflows.Validators; + +/// +/// A validator for instances. +/// +public class WorkflowPropertiesModelValidator : AbstractValidator +{ + + public WorkflowPropertiesModelValidator(IWorkflowDefinitionService workflowDefinitionService, ILocalizer localizer) + { + RuleFor(x => x.Name).NotEmpty().WithMessage(localizer["Please enter a name for the workflow."]); + + RuleFor(x => x.Name) + .MustAsync((context, name, cancellationToken) => workflowDefinitionService.GetIsNameUniqueAsync(name!, context.DefinitionId, cancellationToken)) + .WithMessage(localizer["A workflow with this name already exists."]); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionInfoWidget.cs b/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionInfoWidget.cs new file mode 100644 index 0000000..11e65cb --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionInfoWidget.cs @@ -0,0 +1,24 @@ +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Properties.Sections.Info; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Widgets; + +/// +/// A widget that renders the workflow definition info. +/// +public class WorkflowDefinitionInfoWidget : WorkflowDefinitionPropertiesWidgetBase +{ + /// + public override double Order => 30; + + /// + public override Func, RenderFragment> Render => attributes => + { + return builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, nameof(Info.WorkflowDefinition), attributes["WorkflowDefinition"]); + builder.CloseComponent(); + }; + }; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionMetadataWidget.cs b/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionMetadataWidget.cs new file mode 100644 index 0000000..adc3e67 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionMetadataWidget.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Properties.Sections.Metadata; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Widgets; + +/// +/// A widget that renders the workflow definition metadata. +/// +public class WorkflowDefinitionMetadataWidget : WorkflowDefinitionPropertiesWidgetBase +{ + /// + public override double Order => 10; + + /// + public override Func, RenderFragment> Render => attributes => + { + return builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, nameof(Metadata.WorkflowDefinition), attributes["WorkflowDefinition"]); + builder.AddAttribute(2, nameof(Metadata.WorkflowDefinitionUpdated), attributes["WorkflowDefinitionUpdated"]); + builder.CloseComponent(); + }; + }; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionPropertiesWidgetBase.cs b/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionPropertiesWidgetBase.cs new file mode 100644 index 0000000..e457fbf --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionPropertiesWidgetBase.cs @@ -0,0 +1,20 @@ +using Elsa.Studio.Contracts; +using Elsa.Studio.Workflows.Constants; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Widgets; + +/// +/// A widget that renders the workflow definition info. +/// +public abstract class WorkflowDefinitionPropertiesWidgetBase : IWidget +{ + /// + public string Zone => ZoneNames.WorkflowDefinitionProperties; + + /// + public virtual double Order => 0; + + /// + public abstract Func, RenderFragment> Render { get; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionSettingsWidget.cs b/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionSettingsWidget.cs new file mode 100644 index 0000000..f4a6468 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/Widgets/WorkflowDefinitionSettingsWidget.cs @@ -0,0 +1,25 @@ +using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.WorkflowProperties.Tabs.Properties.Sections.Settings; +using Microsoft.AspNetCore.Components; + +namespace Elsa.Studio.Workflows.Widgets; + +/// +/// A widget that renders the workflow definition settings. +/// +public class WorkflowDefinitionSettingsWidget : WorkflowDefinitionPropertiesWidgetBase +{ + /// + public override double Order => 20; + + /// + public override Func, RenderFragment> Render => attributes => + { + return builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, nameof(Settings.WorkflowDefinition), attributes["WorkflowDefinition"]); + builder.AddAttribute(2, nameof(Settings.WorkflowDefinitionUpdated), attributes["WorkflowDefinitionUpdated"]); + builder.CloseComponent(); + }; + }; +} \ No newline at end of file diff --git a/src/modules/Elsa.Studio.Workflows/_Imports.razor b/src/modules/Elsa.Studio.Workflows/_Imports.razor new file mode 100644 index 0000000..075b312 --- /dev/null +++ b/src/modules/Elsa.Studio.Workflows/_Imports.razor @@ -0,0 +1,25 @@ +@using System.ComponentModel.DataAnnotations +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.AspNetCore.Components.Forms +@using Blazored.FluentValidation +@using Elsa.Studio.Localization +@using Elsa.Studio.Components +@using Elsa.Studio.Workflows.Components +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components +@using Elsa.Studio.Workflows.Components.WorkflowInstanceViewer +@using Elsa.Studio.Workflows.Components.WorkflowInstanceViewer.Components +@using Elsa.Studio.Workflows.Components.WorkflowDefinitionList +@using Elsa.Studio.Workflows.Components.WorkflowInstanceList +@using Elsa.Studio.Workflows.Constants +@using Elsa.Studio.Workflows.Designer.Components +@using Elsa.Studio.Workflows.Shared.Components +@using Elsa.Studio.Localization.Time.Components +@using Humanizer +@using MudBlazor +@using MudExtensions +@using Radzen +@using Radzen.Blazor +@attribute [Authorize] \ No newline at end of file diff --git a/src/wrappers/.gitignore b/src/wrappers/.gitignore new file mode 100644 index 0000000..18d5e87 --- /dev/null +++ b/src/wrappers/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +public/ \ No newline at end of file diff --git a/src/wrappers/lerna.json b/src/wrappers/lerna.json new file mode 100644 index 0000000..f6604bd --- /dev/null +++ b/src/wrappers/lerna.json @@ -0,0 +1,4 @@ +{ + "$schema": "node_modules/lerna/schemas/lerna-schema.json", + "version": "0.0.0" +} diff --git a/src/wrappers/package-lock.json b/src/wrappers/package-lock.json new file mode 100644 index 0000000..fcd10cb --- /dev/null +++ b/src/wrappers/package-lock.json @@ -0,0 +1,14173 @@ +{ + "name": "root", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "root", + "workspaces": [ + "wrappers/*" + ], + "devDependencies": { + "lerna": "^8.2.1" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.3.tgz", + "integrity": "sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz", + "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", + "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.4", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.4", + "@babel/types": "^7.27.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", + "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", + "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", + "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@elsa-workflows/elsa-studio-wasm": { + "version": "3.4.0", + "resolved": "https://f.feedz.io/elsa-workflows/elsa-3/npm/%40elsa-workflows%2felsa-studio-wasm/3.4.0/download", + "integrity": "sha512-DvUyZ1tUkD+oi3UuG7cDEBUrZwvA7lQHUdpknFPT3OJFkzwrj1tiePaR+p5nRad1Dh7yWwZL8XxrsCjECGLhOg==", + "license": "MIT" + }, + "node_modules/@elsa-workflows/elsa-studio-wasm-react": { + "resolved": "wrappers/react-wrapper", + "link": true + }, + "node_modules/@emnapi/core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", + "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emnapi/wasi-threads": "1.0.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", + "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz", + "integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.3.tgz", + "integrity": "sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.29.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", + "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.2.tgz", + "integrity": "sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.0.tgz", + "integrity": "sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", + "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.5.0.tgz", + "integrity": "sha512-qYDdL7fPwLRI+bJNurVcis+tNgJmvWjH4YTBGXTA8xMuxFrnAz6E5o35iyzyKbq5J5Lr8mJGfrR5GXl+WGwhgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "magic-string": "^0.27.0", + "react-docgen-typescript": "^2.2.2" + }, + "peerDependencies": { + "typescript": ">= 4.3.x", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lerna/create": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-8.2.2.tgz", + "integrity": "sha512-1yn1MvWn2Yz0SFgTTQnef2m1YedF7KwqLLVIOrGkgQrkVHzsveAIk1A1RcRa2yyUh+siKI1YcJ7lUZIEt+qQ3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@npmcli/arborist": "7.5.4", + "@npmcli/package-json": "5.2.0", + "@npmcli/run-script": "8.1.0", + "@nx/devkit": ">=17.1.2 < 21", + "@octokit/plugin-enterprise-rest": "6.0.1", + "@octokit/rest": "20.1.2", + "aproba": "2.0.0", + "byte-size": "8.1.1", + "chalk": "4.1.0", + "clone-deep": "4.0.1", + "cmd-shim": "6.0.3", + "color-support": "1.1.3", + "columnify": "1.6.0", + "console-control-strings": "^1.1.0", + "conventional-changelog-core": "5.0.1", + "conventional-recommended-bump": "7.0.1", + "cosmiconfig": "9.0.0", + "dedent": "1.5.3", + "execa": "5.0.0", + "fs-extra": "^11.2.0", + "get-stream": "6.0.0", + "git-url-parse": "14.0.0", + "glob-parent": "6.0.2", + "globby": "11.1.0", + "graceful-fs": "4.2.11", + "has-unicode": "2.0.1", + "ini": "^1.3.8", + "init-package-json": "6.0.3", + "inquirer": "^8.2.4", + "is-ci": "3.0.1", + "is-stream": "2.0.0", + "js-yaml": "4.1.0", + "libnpmpublish": "9.0.9", + "load-json-file": "6.2.0", + "lodash": "^4.17.21", + "make-dir": "4.0.0", + "minimatch": "3.0.5", + "multimatch": "5.0.0", + "node-fetch": "2.6.7", + "npm-package-arg": "11.0.2", + "npm-packlist": "8.0.2", + "npm-registry-fetch": "^17.1.0", + "nx": ">=17.1.2 < 21", + "p-map": "4.0.0", + "p-map-series": "2.1.0", + "p-queue": "6.6.2", + "p-reduce": "^2.1.0", + "pacote": "^18.0.6", + "pify": "5.0.0", + "read-cmd-shim": "4.0.0", + "resolve-from": "5.0.0", + "rimraf": "^4.4.1", + "semver": "^7.3.4", + "set-blocking": "^2.0.0", + "signal-exit": "3.0.7", + "slash": "^3.0.0", + "ssri": "^10.0.6", + "string-width": "^4.2.3", + "strong-log-transformer": "2.1.0", + "tar": "6.2.1", + "temp-dir": "1.0.0", + "upath": "2.0.1", + "uuid": "^10.0.0", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "5.0.1", + "wide-align": "1.1.5", + "write-file-atomic": "5.0.1", + "write-pkg": "4.0.0", + "yargs": "17.7.2", + "yargs-parser": "21.1.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@lerna/create/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@lerna/create/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lerna/create/node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@lerna/create/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/create/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/create/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@lerna/create/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/create/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/create/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", + "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz", + "integrity": "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emnapi/core": "^1.1.0", + "@emnapi/runtime": "^1.1.0", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/arborist": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-7.5.4.tgz", + "integrity": "sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.1", + "@npmcli/installed-package-contents": "^2.1.0", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^7.1.1", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.1.0", + "@npmcli/query": "^3.1.0", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", + "bin-links": "^4.0.4", + "cacache": "^18.0.3", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^7.0.2", + "json-parse-even-better-errors": "^3.0.2", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^7.2.1", + "npm-install-checks": "^6.2.0", + "npm-package-arg": "^11.0.2", + "npm-pick-manifest": "^9.0.1", + "npm-registry-fetch": "^17.0.1", + "pacote": "^18.0.6", + "parse-conflict-json": "^3.0.0", + "proc-log": "^4.2.0", + "proggy": "^2.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.6", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/arborist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/arborist/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/arborist/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/arborist/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/git": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", + "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/git/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", + "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz", + "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/metavuln-calculator": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-7.1.1.tgz", + "integrity": "sha512-Nkxf96V0lAx3HCpVda7Vw4P23RILgdi/5K1fmj2tZkWIYLpXAN8k2UVVOsW16TsS5F8Ws2I7Cm+PU1/rsVF47g==", + "dev": true, + "license": "ISC", + "dependencies": { + "cacache": "^18.0.0", + "json-parse-even-better-errors": "^3.0.0", + "pacote": "^18.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/metavuln-calculator/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz", + "integrity": "sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.0.tgz", + "integrity": "sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", + "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/query": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-3.1.0.tgz", + "integrity": "sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", + "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.1.0.tgz", + "integrity": "sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@nx/devkit": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-20.8.2.tgz", + "integrity": "sha512-rr9p2/tZDQivIpuBUpZaFBK6bZ+b5SAjZk75V4tbCUqGW3+5OPuVvBPm+X+7PYwUF6rwSpewxkjWNeGskfCe+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ejs": "^3.1.7", + "enquirer": "~2.3.6", + "ignore": "^5.0.4", + "minimatch": "9.0.3", + "semver": "^7.5.3", + "tmp": "~0.2.1", + "tslib": "^2.3.0", + "yargs-parser": "21.1.1" + }, + "peerDependencies": { + "nx": ">= 19 <= 21" + } + }, + "node_modules/@nx/devkit/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@nx/devkit/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nx/devkit/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nx/nx-darwin-arm64": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-20.8.2.tgz", + "integrity": "sha512-t+bmCn6sRPNGU6hnSyWNvbQYA/KgsxGZKYlaCLRwkNhI2akModcBUqtktJzCKd1XHDqs6EkEFBWjFr8/kBEkSg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-darwin-x64": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-20.8.2.tgz", + "integrity": "sha512-pt/wmDLM31Es8/EzazlyT5U+ou2l60rfMNFGCLqleHEQ0JUTc0KWnOciBLbHIQFiPsCQZJFEKyfV5V/ncePmmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-freebsd-x64": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-20.8.2.tgz", + "integrity": "sha512-joZxFbgJfkHkB9uMIJr73Gpnm9pnpvr0XKGbWC409/d2x7q1qK77tKdyhGm+A3+kaZFwstNVPmCUtUwJYyU6LA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-20.8.2.tgz", + "integrity": "sha512-98O/qsxn4vIMPY/FyzvmVrl7C5yFhCUVk0/4PF+PA2SvtQ051L1eMRY6bq/lb69qfN6szJPZ41PG5mPx0NeLZw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-20.8.2.tgz", + "integrity": "sha512-h6a+HxwfSpxsi4KpxGgPh9GDBmD2E+XqGCdfYpobabxqEBvlnIlJyuDhlRR06cTWpuNXHpRdrVogmV6m/YbtDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-20.8.2.tgz", + "integrity": "sha512-4Ev+jM0VAxDHV/dFgMXjQTCXS4I8W4oMe7FSkXpG8RUn6JK659DC8ExIDPoGIh+Cyqq6r6mw1CSia+ciQWICWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-20.8.2.tgz", + "integrity": "sha512-nR0ev+wxu+nQYRd7bhqggOxK7UfkV6h+Ko1mumUFyrM5GvPpz/ELhjJFSnMcOkOMcvH0b6G5uTBJvN1XWCkbmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-musl": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-20.8.2.tgz", + "integrity": "sha512-ost41l5yc2aq2Gc9bMMpaPi/jkXqbXEMEPHrxWKuKmaek3K2zbVDQzvBBNcQKxf/mlCsrqN4QO0mKYSRRqag5A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-20.8.2.tgz", + "integrity": "sha512-0SEOqT/daBG5WtM9vOGilrYaAuf1tiALdrFavY62+/arXYxXemUKmRI5qoKDTnvoLMBGkJs6kxhMO5b7aUXIvQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-20.8.2.tgz", + "integrity": "sha512-iIsY+tVqes/NOqTbJmggL9Juie/iaDYlWgXA9IUv88FE9thqWKhVj4/tCcPjsOwzD+1SVna3YISEEFsx5UV4ew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.1.tgz", + "integrity": "sha512-dKYCMuPO1bmrpuogcjQ8z7ICCH3FP6WmxpwC03yjzGfZhj9fTJg6+bS1+UAplekbN2C+M61UNllGOOoAfGCrdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", + "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", + "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-enterprise-rest": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz", + "integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.4-cjs.2.tgz", + "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.2-cjs.1.tgz", + "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.8.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", + "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", + "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.2.tgz", + "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.11", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz", + "integrity": "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", + "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz", + "integrity": "sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.0.tgz", + "integrity": "sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.0.tgz", + "integrity": "sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.0.tgz", + "integrity": "sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.0.tgz", + "integrity": "sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.0.tgz", + "integrity": "sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.0.tgz", + "integrity": "sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.0.tgz", + "integrity": "sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.0.tgz", + "integrity": "sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.0.tgz", + "integrity": "sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.0.tgz", + "integrity": "sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.0.tgz", + "integrity": "sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.0.tgz", + "integrity": "sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.0.tgz", + "integrity": "sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.0.tgz", + "integrity": "sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.0.tgz", + "integrity": "sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.0.tgz", + "integrity": "sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.0.tgz", + "integrity": "sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.0.tgz", + "integrity": "sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.0.tgz", + "integrity": "sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sigstore/bundle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", + "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", + "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.3.tgz", + "integrity": "sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", + "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", + "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", + "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/addon-actions": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.14.tgz", + "integrity": "sha512-mDQxylxGGCQSK7tJPkD144J8jWh9IU9ziJMHfB84PKpI/V5ZgqMDnpr2bssTrUaGDqU5e1/z8KcRF+Melhs9pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@types/uuid": "^9.0.1", + "dequal": "^2.0.2", + "polished": "^4.2.2", + "uuid": "^9.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-actions/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@storybook/addon-backgrounds": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.14.tgz", + "integrity": "sha512-l9xS8qWe5n4tvMwth09QxH2PmJbCctEvBAc1tjjRasAfrd69f7/uFK4WhwJAstzBTNgTc8VXI4w8ZR97i1sFbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "memoizerific": "^1.11.3", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-controls": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.14.tgz", + "integrity": "sha512-IiQpkNJdiRyA4Mq9mzjZlvQugL/aE7hNgVxBBGPiIZG6wb6Ht9hNnBYpap5ZXXFKV9p2qVI0FZK445ONmAa+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "dequal": "^2.0.2", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-docs": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.14.tgz", + "integrity": "sha512-Obpd0OhAF99JyU5pp5ci17YmpcQtMNgqW2pTXV8jAiiipWpwO++hNDeQmLmlSXB399XjtRDOcDVkoc7rc6JzdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdx-js/react": "^3.0.0", + "@storybook/blocks": "8.6.14", + "@storybook/csf-plugin": "8.6.14", + "@storybook/react-dom-shim": "8.6.14", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-essentials": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.14.tgz", + "integrity": "sha512-5ZZSHNaW9mXMOFkoPyc3QkoNGdJHETZydI62/OASR0lmPlJ1065TNigEo5dJddmZNn0/3bkE8eKMAzLnO5eIdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/addon-actions": "8.6.14", + "@storybook/addon-backgrounds": "8.6.14", + "@storybook/addon-controls": "8.6.14", + "@storybook/addon-docs": "8.6.14", + "@storybook/addon-highlight": "8.6.14", + "@storybook/addon-measure": "8.6.14", + "@storybook/addon-outline": "8.6.14", + "@storybook/addon-toolbars": "8.6.14", + "@storybook/addon-viewport": "8.6.14", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-highlight": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.14.tgz", + "integrity": "sha512-4H19OJlapkofiE9tM6K/vsepf4ir9jMm9T+zw5L85blJZxhKZIbJ6FO0TCG9PDc4iPt3L6+aq5B0X29s9zicNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-interactions": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.14.tgz", + "integrity": "sha512-8VmElhm2XOjh22l/dO4UmXxNOolGhNiSpBcls2pqWSraVh4a670EyYBZsHpkXqfNHo2YgKyZN3C91+9zfH79qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/instrumenter": "8.6.14", + "@storybook/test": "8.6.14", + "polished": "^4.2.2", + "ts-dedent": "^2.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-links": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.6.14.tgz", + "integrity": "sha512-DRlXHIyZzOruAZkxmXfVgTF+4d6K27pFcH4cUsm3KT1AXuZbr23lb5iZHpUZoG6lmU85Sru4xCEgewSTXBIe1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.6.14" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/@storybook/addon-measure": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.14.tgz", + "integrity": "sha512-1Tlyb72NX8aAqm6I6OICsUuGOP6hgnXcuFlXucyhKomPa6j3Eu2vKu561t/f0oGtAK2nO93Z70kVaEh5X+vaGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "tiny-invariant": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-onboarding": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.6.14.tgz", + "integrity": "sha512-bHdHiGJFigVcSzMIsNLHY5IODZHr+nKwyz5/QOZLMkLcGH2IaUbOJfm4RyGOaTTPsUtAKbdsVXNEG3Otf+qO9A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-outline": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.14.tgz", + "integrity": "sha512-CW857JvN6OxGWElqjlzJO2S69DHf+xO3WsEfT5mT3ZtIjmsvRDukdWfDU9bIYUFyA2lFvYjncBGjbK+I91XR7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-toolbars": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.14.tgz", + "integrity": "sha512-W/wEXT8h3VyZTVfWK/84BAcjAxTdtRiAkT2KAN0nbSHxxB5KEM1MjKpKu2upyzzMa3EywITqbfy4dP6lpkVTwQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-viewport": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.14.tgz", + "integrity": "sha512-gNzVQbMqRC+/4uQTPI2ZrWuRHGquTMZpdgB9DrD88VTEjNudP+J6r8myLfr2VvGksBbUMHkGHMXHuIhrBEnXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "memoizerific": "^1.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/blocks": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.14.tgz", + "integrity": "sha512-rBMHAfA39AGHgkrDze4RmsnQTMw1ND5fGWobr9pDcJdnDKWQWNRD7Nrlxj0gFlN3n4D9lEZhWGdFrCbku7FVAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/icons": "^1.2.12", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^8.6.14" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@storybook/builder-vite": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.6.14.tgz", + "integrity": "sha512-ajWYhy32ksBWxwWHrjwZzyC0Ii5ZTeu5lsqA95Q/EQBB0P5qWlHWGM3AVyv82Mz/ND03ebGy123uVwgf6olnYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/csf-plugin": "8.6.14", + "browser-assert": "^1.2.1", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14", + "vite": "^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@storybook/components": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.14.tgz", + "integrity": "sha512-HNR2mC5I4Z5ek8kTrVZlIY/B8gJGs5b3XdZPBPBopTIN6U/YHXiDyOjY3JlaS4fSG1fVhp/Qp1TpMn1w/9m1pw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@storybook/core": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.14.tgz", + "integrity": "sha512-1P/w4FSNRqP8j3JQBOi3yGt8PVOgSRbP66Ok520T78eJBeqx9ukCfl912PQZ7SPbW3TIunBwLXMZOjZwBB/JmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/theming": "8.6.14", + "better-opn": "^3.0.2", + "browser-assert": "^1.2.1", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", + "esbuild-register": "^3.5.0", + "jsdoc-type-pratt-parser": "^4.0.0", + "process": "^0.11.10", + "recast": "^0.23.5", + "semver": "^7.6.2", + "util": "^0.12.5", + "ws": "^8.2.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/@storybook/core/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@storybook/csf": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.13.tgz", + "integrity": "sha512-7xOOwCLGB3ebM87eemep89MYRFTko+D8qE7EdAAq74lgdqRR5cOUtYWJLjO2dLtP94nqoOdHJo6MdLLKzg412Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^2.19.0" + } + }, + "node_modules/@storybook/csf-plugin": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.14.tgz", + "integrity": "sha512-dErtc9teAuN+eelN8FojzFE635xlq9cNGGGEu0WEmMUQ4iJ8pingvBO1N8X3scz4Ry7KnxX++NNf3J3gpxS8qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "unplugin": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/icons": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.4.0.tgz", + "integrity": "sha512-Td73IeJxOyalzvjQL+JXx72jlIYHgs+REaHiREOqfpo3A2AYYG71AUbcv+lg7mEDIweKVCxsMQ0UKo634c8XeA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta" + } + }, + "node_modules/@storybook/instrumenter": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.14.tgz", + "integrity": "sha512-iG4MlWCcz1L7Yu8AwgsnfVAmMbvyRSk700Mfy2g4c8y5O+Cv1ejshE1LBBsCwHgkuqU0H4R0qu4g23+6UnUemQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@vitest/utils": "^2.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/manager-api": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.14.tgz", + "integrity": "sha512-ez0Zihuy17udLbfHZQXkGqwtep0mSGgHcNzGN7iZrMP1m+VmNo+7aGCJJdvXi7+iU3yq8weXSQFWg5DqWgLS7g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@storybook/preview-api": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.14.tgz", + "integrity": "sha512-2GhcCd4dNMrnD7eooEfvbfL4I83qAqEyO0CO7JQAmIO6Rxb9BsOLLI/GD5HkvQB73ArTJ+PT50rfaO820IExOQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@storybook/react": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.14.tgz", + "integrity": "sha512-BOepx5bBFwl/CPI+F+LnmMmsG1wQYmrX/UQXgUbHQUU9Tj7E2ndTnNbpIuSLc8IrM03ru+DfwSg1Co3cxWtT+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/components": "8.6.14", + "@storybook/global": "^5.0.0", + "@storybook/manager-api": "8.6.14", + "@storybook/preview-api": "8.6.14", + "@storybook/react-dom-shim": "8.6.14", + "@storybook/theming": "8.6.14" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@storybook/test": "8.6.14", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.6.14", + "typescript": ">= 4.2.x" + }, + "peerDependenciesMeta": { + "@storybook/test": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-dom-shim": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.14.tgz", + "integrity": "sha512-0hixr3dOy3f3M+HBofp3jtMQMS+sqzjKNgl7Arfuj3fvjmyXOks/yGjDImySR4imPtEllvPZfhiQNlejheaInw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/react-vite": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.6.14.tgz", + "integrity": "sha512-FZU0xMPxa4/TO87FgcWwappOxLBHZV5HSRK5K+2bJD7rFJAoNorbHvB4Q1zvIAk7eCMjkr2GPCPHx9PRB9vJFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@joshwooding/vite-plugin-react-docgen-typescript": "0.5.0", + "@rollup/pluginutils": "^5.0.2", + "@storybook/builder-vite": "8.6.14", + "@storybook/react": "8.6.14", + "find-up": "^5.0.0", + "magic-string": "^0.30.0", + "react-docgen": "^7.0.0", + "resolve": "^1.22.8", + "tsconfig-paths": "^4.2.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@storybook/test": "8.6.14", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.6.14", + "vite": "^4.0.0 || ^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "@storybook/test": { + "optional": true + } + } + }, + "node_modules/@storybook/test": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.14.tgz", + "integrity": "sha512-GkPNBbbZmz+XRdrhMtkxPotCLOQ1BaGNp/gFZYdGDk2KmUWBKmvc5JxxOhtoXM2703IzNFlQHSSNnhrDZYuLlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/instrumenter": "8.6.14", + "@testing-library/dom": "10.4.0", + "@testing-library/jest-dom": "6.5.0", + "@testing-library/user-event": "14.5.2", + "@vitest/expect": "2.0.5", + "@vitest/spy": "2.0.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/testing-library": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.2.tgz", + "integrity": "sha512-L8sXFJUHmrlyU2BsWWZGuAjv39Jl1uAqUHdxmN42JY15M4+XCMjGlArdCCjDe1wpTSW6USYISA9axjZojgtvnw==", + "deprecated": "In Storybook 8, this package functionality has been integrated to a new package called @storybook/test, which uses Vitest APIs for an improved experience. When upgrading to Storybook 8 with 'npx storybook@latest upgrade', you will get prompted and will get an automigration for the new package. Please migrate when you can.", + "dev": true, + "license": "MIT", + "dependencies": { + "@testing-library/dom": "^9.0.0", + "@testing-library/user-event": "^14.4.0", + "ts-dedent": "^2.2.0" + } + }, + "node_modules/@storybook/testing-library/node_modules/@testing-library/dom": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@storybook/testing-library/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@storybook/theming": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.14.tgz", + "integrity": "sha512-r4y+LsiB37V5hzpQo+BM10PaCsp7YlZ0YcZzQP1OCkPlYXmUAFy2VvDKaFRpD8IeNPKug2u4iFm/laDEbs03dg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", + "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", + "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.1.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", + "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.1.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", + "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.34.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.1.tgz", + "integrity": "sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.34.1", + "@typescript-eslint/types": "^8.34.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.34.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.1.tgz", + "integrity": "sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.34.1", + "@typescript-eslint/visitor-keys": "8.34.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.34.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.1.tgz", + "integrity": "sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.34.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.1.tgz", + "integrity": "sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.34.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.1.tgz", + "integrity": "sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.34.1", + "@typescript-eslint/tsconfig-utils": "8.34.1", + "@typescript-eslint/types": "8.34.1", + "@typescript-eslint/visitor-keys": "8.34.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.34.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.1.tgz", + "integrity": "sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.34.1", + "@typescript-eslint/types": "8.34.1", + "@typescript-eslint/typescript-estree": "8.34.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.34.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.1.tgz", + "integrity": "sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.34.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.2.tgz", + "integrity": "sha512-QNVT3/Lxx99nMQWJWF7K4N6apUEuT0KlZA3mx/mVaoGj3smm/8rc8ezz15J1pcbcjDK0V15rpHetVfya08r76Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.11", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + } + }, + "node_modules/@vitest/expect": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", + "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/pretty-format": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", + "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", + "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.0.5", + "estree-walker": "^3.0.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", + "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/@yarnpkg/parsers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.2.tgz", + "integrity": "sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@zkochan/js-yaml": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.7.tgz", + "integrity": "sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/better-opn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", + "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "open": "^8.0.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/bin-links": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.4.tgz", + "integrity": "sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-assert": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz", + "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", + "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001718", + "electron-to-chromium": "^1.5.160", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/byte-size": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz", + "integrity": "sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001724", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz", + "integrity": "sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cmd-shim": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.3.tgz", + "integrity": "sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/columnify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", + "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/columnify/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "dev": true, + "license": "ISC" + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-changelog-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz", + "integrity": "sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^6.0.0", + "conventional-commits-parser": "^4.0.0", + "dateformat": "^3.0.3", + "get-pkg-repo": "^4.2.1", + "git-raw-commits": "^3.0.0", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^5.0.0", + "normalize-package-data": "^3.0.3", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-changelog-core/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/conventional-changelog-preset-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz", + "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", + "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-commits-filter": "^3.0.0", + "dateformat": "^3.0.3", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^8.1.2", + "semver": "^7.0.0", + "split": "^1.0.1" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-commits-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", + "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-recommended-bump": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz", + "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^3.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "git-raw-commits": "^3.0.0", + "git-semver-tags": "^5.0.0", + "meow": "^8.1.2" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.171", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.171.tgz", + "integrity": "sha512-scWpzXEJEMrGJa4Y6m/tVotb0WuvNmasv3wWVzUAeCgKU0ToFOhUW6Z+xWnRQANMYGxN4ngJXIThgBJOqzVPCQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/envinfo": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/esbuild-register": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "esbuild": ">=0.12 <1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.29.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz", + "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.1", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.29.0", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", + "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-storybook": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.12.0.tgz", + "integrity": "sha512-Lg5I0+npTgiYgZ4KSvGWGDFZi3eOCNJPaWX0c9rTEEXC5wvooOClsP9ZtbI4hhFKyKgYR877KiJxbRTSJq9gWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/csf": "^0.1.11", + "@typescript-eslint/utils": "^8.8.1", + "ts-dedent": "^2.2.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", + "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/front-matter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", + "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1" + } + }, + "node_modules/front-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/front-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/front-matter/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/get-pkg-repo/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/get-pkg-repo/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-pkg-repo/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-pkg-repo/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/get-pkg-repo/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/get-pkg-repo/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/git-raw-commits": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", + "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^7.0.0", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-remote-origin-url/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/git-semver-tags": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz", + "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "meow": "^8.1.2", + "semver": "^7.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/git-semver-tags/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", + "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^8.1.0" + } + }, + "node_modules/git-url-parse": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-14.0.0.tgz", + "integrity": "sha512-NnLweV+2A4nCvn4U/m2AoYu0pPKlsmhK9cknG7IMwsjFY1S2jxM+mAhsDxyxfCIGfGaD+dozsyX4b6vkYc83yQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "git-up": "^7.0.0" + } + }, + "node_modules/gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", + "dev": true, + "license": "BSD", + "dependencies": { + "ini": "^1.3.2" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", + "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/init-package-json": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-6.0.3.tgz", + "integrity": "sha512-Zfeb5ol+H+eqJWHTaGca9BovufyGeIfr4zaaBorPmJBMrJ+KBnN+kQx2ZtXdsotUTgldHmHQV44xvUWOUA7E2w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^5.0.0", + "npm-package-arg": "^11.0.0", + "promzard": "^1.0.0", + "read": "^3.0.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/init-package-json/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-nice": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", + "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/just-diff": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-6.0.2.tgz", + "integrity": "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==", + "dev": true, + "license": "MIT" + }, + "node_modules/just-diff-apply": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz", + "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lerna": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-8.2.2.tgz", + "integrity": "sha512-GkqBELTG4k7rfzAwRok2pKBvhNo046Hfwcj7TuhDah3q58/BBBAqvIFLfqEI5fglnNOs6maMSn6/MWjccQE55A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lerna/create": "8.2.2", + "@npmcli/arborist": "7.5.4", + "@npmcli/package-json": "5.2.0", + "@npmcli/run-script": "8.1.0", + "@nx/devkit": ">=17.1.2 < 21", + "@octokit/plugin-enterprise-rest": "6.0.1", + "@octokit/rest": "20.1.2", + "aproba": "2.0.0", + "byte-size": "8.1.1", + "chalk": "4.1.0", + "clone-deep": "4.0.1", + "cmd-shim": "6.0.3", + "color-support": "1.1.3", + "columnify": "1.6.0", + "console-control-strings": "^1.1.0", + "conventional-changelog-angular": "7.0.0", + "conventional-changelog-core": "5.0.1", + "conventional-recommended-bump": "7.0.1", + "cosmiconfig": "9.0.0", + "dedent": "1.5.3", + "envinfo": "7.13.0", + "execa": "5.0.0", + "fs-extra": "^11.2.0", + "get-port": "5.1.1", + "get-stream": "6.0.0", + "git-url-parse": "14.0.0", + "glob-parent": "6.0.2", + "globby": "11.1.0", + "graceful-fs": "4.2.11", + "has-unicode": "2.0.1", + "import-local": "3.1.0", + "ini": "^1.3.8", + "init-package-json": "6.0.3", + "inquirer": "^8.2.4", + "is-ci": "3.0.1", + "is-stream": "2.0.0", + "jest-diff": ">=29.4.3 < 30", + "js-yaml": "4.1.0", + "libnpmaccess": "8.0.6", + "libnpmpublish": "9.0.9", + "load-json-file": "6.2.0", + "lodash": "^4.17.21", + "make-dir": "4.0.0", + "minimatch": "3.0.5", + "multimatch": "5.0.0", + "node-fetch": "2.6.7", + "npm-package-arg": "11.0.2", + "npm-packlist": "8.0.2", + "npm-registry-fetch": "^17.1.0", + "nx": ">=17.1.2 < 21", + "p-map": "4.0.0", + "p-map-series": "2.1.0", + "p-pipe": "3.1.0", + "p-queue": "6.6.2", + "p-reduce": "2.1.0", + "p-waterfall": "2.1.1", + "pacote": "^18.0.6", + "pify": "5.0.0", + "read-cmd-shim": "4.0.0", + "resolve-from": "5.0.0", + "rimraf": "^4.4.1", + "semver": "^7.3.8", + "set-blocking": "^2.0.0", + "signal-exit": "3.0.7", + "slash": "3.0.0", + "ssri": "^10.0.6", + "string-width": "^4.2.3", + "strong-log-transformer": "2.1.0", + "tar": "6.2.1", + "temp-dir": "1.0.0", + "typescript": ">=3 < 6", + "upath": "2.0.1", + "uuid": "^10.0.0", + "validate-npm-package-license": "3.0.4", + "validate-npm-package-name": "5.0.1", + "wide-align": "1.1.5", + "write-file-atomic": "5.0.1", + "write-pkg": "4.0.0", + "yargs": "17.7.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "lerna": "dist/cli.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/lerna/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lerna/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/lerna/node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/lerna/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lerna/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lerna/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/lerna/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lerna/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lerna/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libnpmaccess": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-8.0.6.tgz", + "integrity": "sha512-uM8DHDEfYG6G5gVivVl+yQd4pH3uRclHC59lzIbSvy7b5FEwR+mU49Zq1jEyRtRFv7+M99mUW9S0wL/4laT4lw==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/libnpmpublish": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-9.0.9.tgz", + "integrity": "sha512-26zzwoBNAvX9AWOPiqqF6FG4HrSCPsHFkQm7nT+xU1ggAujL/eae81RnCv4CJ2In9q9fh10B88sYSzKCUh/Ghg==", + "dev": true, + "license": "ISC", + "dependencies": { + "ci-info": "^4.0.0", + "normalize-package-data": "^6.0.1", + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.1", + "proc-log": "^4.2.0", + "semver": "^7.3.7", + "sigstore": "^2.2.0", + "ssri": "^10.0.6" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/libnpmpublish/node_modules/ci-info": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", + "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/libnpmpublish/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/load-json-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", + "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/load-json-file/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz", + "integrity": "sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/map-or-similar": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", + "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", + "dev": true, + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memoizerific": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", + "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-or-similar": "^1.5.0" + } + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/meow/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/multimatch/node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz", + "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-machine-id": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", + "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-bundled": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", + "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", + "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-packlist": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", + "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", + "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-registry-fetch": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", + "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/nx/-/nx-20.8.2.tgz", + "integrity": "sha512-mDKpbH3vEpUFDx0rrLh+tTqLq1PYU8KiD/R7OVZGd1FxQxghx2HOl32MiqNsfPcw6AvKlXhslbwIESV+N55FLQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@napi-rs/wasm-runtime": "0.2.4", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "3.0.2", + "@zkochan/js-yaml": "0.0.7", + "axios": "^1.8.3", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^8.0.1", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "enquirer": "~2.3.6", + "figures": "3.2.0", + "flat": "^5.0.2", + "front-matter": "^4.0.2", + "ignore": "^5.0.4", + "jest-diff": "^29.4.1", + "jsonc-parser": "3.2.0", + "lines-and-columns": "2.0.3", + "minimatch": "9.0.3", + "node-machine-id": "1.1.12", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "ora": "5.3.0", + "resolve.exports": "2.0.3", + "semver": "^7.5.3", + "string-width": "^4.2.3", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "yaml": "^2.6.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js", + "nx-cloud": "bin/nx-cloud.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "20.8.2", + "@nx/nx-darwin-x64": "20.8.2", + "@nx/nx-freebsd-x64": "20.8.2", + "@nx/nx-linux-arm-gnueabihf": "20.8.2", + "@nx/nx-linux-arm64-gnu": "20.8.2", + "@nx/nx-linux-arm64-musl": "20.8.2", + "@nx/nx-linux-x64-gnu": "20.8.2", + "@nx/nx-linux-x64-musl": "20.8.2", + "@nx/nx-win32-arm64-msvc": "20.8.2", + "@nx/nx-win32-x64-msvc": "20.8.2" + }, + "peerDependencies": { + "@swc-node/register": "^1.8.0", + "@swc/core": "^1.3.85" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/nx/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/nx/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/nx/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nx/node_modules/ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nx/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nx/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz", + "integrity": "sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-pipe": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz", + "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-waterfall": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz", + "integrity": "sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-reduce": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz", + "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^8.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-conflict-json": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-3.0.1.tgz", + "integrity": "sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-json/node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-path": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", + "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "node_modules/parse-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", + "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-path": "^7.0.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/polished": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", + "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.8" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/proggy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proggy/-/proggy-2.0.0.tgz", + "integrity": "sha512-69agxLtnI8xBs9gUGqEnK26UfiexpHy+KUpBQWabiytQjnn5wFY8rklAi7GRfABIuPNnQ/ik48+LGLkYYJcy4A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/promise-all-reject-late": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-call-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-3.0.2.tgz", + "integrity": "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promzard": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/promzard/-/promzard-1.0.2.tgz", + "integrity": "sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "read": "^3.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/protocols": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-docgen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.1.1.tgz", + "integrity": "sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.18.9", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9", + "@types/babel__core": "^7.18.0", + "@types/babel__traverse": "^7.18.0", + "@types/doctrine": "^0.0.9", + "@types/resolve": "^1.20.2", + "doctrine": "^3.0.0", + "resolve": "^1.22.1", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=16.14.0" + } + }, + "node_modules/react-docgen-typescript": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz", + "integrity": "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">= 4.3.x" + } + }, + "node_modules/react-docgen/node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/read/-/read-3.0.1.tgz", + "integrity": "sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw==", + "dev": true, + "license": "ISC", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-cmd-shim": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/read-pkg/node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/read/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redent/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup": { + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.0.tgz", + "integrity": "sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.44.0", + "@rollup/rollup-android-arm64": "4.44.0", + "@rollup/rollup-darwin-arm64": "4.44.0", + "@rollup/rollup-darwin-x64": "4.44.0", + "@rollup/rollup-freebsd-arm64": "4.44.0", + "@rollup/rollup-freebsd-x64": "4.44.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.44.0", + "@rollup/rollup-linux-arm-musleabihf": "4.44.0", + "@rollup/rollup-linux-arm64-gnu": "4.44.0", + "@rollup/rollup-linux-arm64-musl": "4.44.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.44.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.44.0", + "@rollup/rollup-linux-riscv64-gnu": "4.44.0", + "@rollup/rollup-linux-riscv64-musl": "4.44.0", + "@rollup/rollup-linux-s390x-gnu": "4.44.0", + "@rollup/rollup-linux-x64-gnu": "4.44.0", + "@rollup/rollup-linux-x64-musl": "4.44.0", + "@rollup/rollup-win32-arm64-msvc": "4.44.0", + "@rollup/rollup-win32-ia32-msvc": "4.44.0", + "@rollup/rollup-win32-x64-msvc": "4.44.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", + "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", + "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "license": "ISC", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/storybook": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.14.tgz", + "integrity": "sha512-sVKbCj/OTx67jhmauhxc2dcr1P+yOgz/x3h0krwjyMgdc5Oubvxyg4NYDZmzAw+ym36g/lzH8N0Ccp4dwtdfxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/core": "8.6.14" + }, + "bin": { + "getstorybook": "bin/index.cjs", + "sb": "bin/index.cjs", + "storybook": "bin/index.cjs" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + }, + "bin": { + "sl-log-transformer": "bin/sl-log-transformer.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/treeverse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-3.0.0.tgz", + "integrity": "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", + "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unplugin": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", + "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/walk-up-path": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", + "dev": true, + "license": "ISC" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wide-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-json-file": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz", + "integrity": "sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-indent": "^5.0.0", + "graceful-fs": "^4.1.15", + "make-dir": "^2.1.0", + "pify": "^4.0.1", + "sort-keys": "^2.0.0", + "write-file-atomic": "^2.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/write-json-file/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/write-json-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/write-json-file/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/write-json-file/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-json-file/node_modules/write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/write-pkg": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-4.0.0.tgz", + "integrity": "sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sort-keys": "^2.0.0", + "type-fest": "^0.4.1", + "write-json-file": "^3.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/write-pkg/node_modules/type-fest": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz", + "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=6" + } + }, + "node_modules/ws": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "wrappers/react-wrapper": { + "name": "@elsa-workflows/elsa-studio-wasm-react", + "version": "0.0.0", + "hasInstallScript": true, + "dependencies": { + "@elsa-workflows/elsa-studio-wasm": "^3.4.0-rc1", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@storybook/addon-essentials": "^8.6.11", + "@storybook/addon-interactions": "^8.6.11", + "@storybook/addon-links": "^8.6.11", + "@storybook/addon-onboarding": "^8.6.11", + "@storybook/blocks": "^8.6.11", + "@storybook/react": "^8.6.11", + "@storybook/react-vite": "^8.6.11", + "@storybook/testing-library": "^0.2.2", + "@types/react": "^19.0.12", + "@types/react-dom": "^19.0.4", + "@vitejs/plugin-react": "^4.3.4", + "eslint": "^9.23.0", + "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "eslint-plugin-storybook": "^0.12.0", + "prop-types": "^15.8.1", + "storybook": "^8.6.11", + "vite": "^6.2.4" + } + } + } +} diff --git a/src/wrappers/package.json b/src/wrappers/package.json new file mode 100644 index 0000000..ca349a8 --- /dev/null +++ b/src/wrappers/package.json @@ -0,0 +1,12 @@ +{ + "name": "root", + "private": true, + "workspaces": [ + "wrappers/*" + ], + "dependencies": { + }, + "devDependencies": { + "lerna": "^8.2.1" + } +} diff --git a/src/wrappers/wrappers/react-wrapper/.eslintrc.cjs b/src/wrappers/wrappers/react-wrapper/.eslintrc.cjs new file mode 100644 index 0000000..c1104af --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/.eslintrc.cjs @@ -0,0 +1,24 @@ +module.exports = { + root: true, + env: { + browser: true, + es2020: true + }, + extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:react/jsx-runtime', 'plugin:react-hooks/recommended', 'plugin:storybook/recommended'], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module' + }, + settings: { + react: { + version: '18.2' + } + }, + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': ['warn', { + allowConstantExport: true + }] + } +}; \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/.gitignore b/src/wrappers/wrappers/react-wrapper/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/src/wrappers/wrappers/react-wrapper/.storybook/main.js b/src/wrappers/wrappers/react-wrapper/.storybook/main.js new file mode 100644 index 0000000..7164f8d --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/.storybook/main.js @@ -0,0 +1,30 @@ +import { join, dirname } from "path"; +import { StorybookConfig } from '@storybook/react-vite'; + +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + */ +function getAbsolutePath(value) { + return dirname(require.resolve(join(value, "package.json"))); +} + +/** @type { import('@storybook/react-vite').StorybookConfig } */ +const config = { + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + addons: [ + getAbsolutePath("@storybook/addon-links"), + getAbsolutePath("@storybook/addon-essentials"), + getAbsolutePath("@storybook/addon-onboarding"), + getAbsolutePath("@storybook/addon-interactions"), + ], + framework: { + name: getAbsolutePath("@storybook/react-vite"), + options: {}, + }, + docs: { + autodocs: "tag", + }, + staticDirs: ['../public'], //👈 Configures the static asset folder in Storybook +}; +export default config; diff --git a/src/wrappers/wrappers/react-wrapper/.storybook/preview-body.html b/src/wrappers/wrappers/react-wrapper/.storybook/preview-body.html new file mode 100644 index 0000000..97c350d --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/.storybook/preview-body.html @@ -0,0 +1,9 @@ +
+ + + + + + + + \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/.storybook/preview-head.html b/src/wrappers/wrappers/react-wrapper/.storybook/preview-head.html new file mode 100644 index 0000000..ecc4f39 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/.storybook/preview-head.html @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/.storybook/preview.js b/src/wrappers/wrappers/react-wrapper/.storybook/preview.js new file mode 100644 index 0000000..3f537aa --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/.storybook/preview.js @@ -0,0 +1,14 @@ +/** @type { import('@storybook/react').Preview } */ +const preview = { + parameters: { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + } +}; + +export default preview; diff --git a/src/wrappers/wrappers/react-wrapper/README.md b/src/wrappers/wrappers/react-wrapper/README.md new file mode 100644 index 0000000..ae8ad1d --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/README.md @@ -0,0 +1,3 @@ +# Elsa Studio React Wrapper + +This package contains a React wrapper for Elsa Studio, a webassembly application for building workflows. \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/package.json b/src/wrappers/wrappers/react-wrapper/package.json new file mode 100644 index 0000000..84f6538 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/package.json @@ -0,0 +1,53 @@ +{ + "name": "@elsa-workflows/elsa-studio-wasm-react", + "version": "0.0.0", + "type": "module", + "files": [ + "dist" + ], + "main": "./dist/elsa-studio-wasm-react.umd.cjs", + "module": "./dist/elsa-studio-wasm-react.js", + "exports": { + ".": { + "import": "./dist/elsa-studio-wasm-react.js", + "require": "./dist/elsa-studio-wasm-react.umd.cjs" + } + }, + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build", + "postinstall": "npm run copy:elsa-studio-wasm", + "copy:elsa-studio-wasm": "cp -r ../../node_modules/@elsa-workflows/elsa-studio-wasm/_content public/ && cp -r ../../node_modules/@elsa-workflows/elsa-studio-wasm/_framework public/ && cp -r ../../node_modules/@elsa-workflows/elsa-studio-wasm/appsettings.json public/" + }, + "dependencies": { + "@elsa-workflows/elsa-studio-wasm": "^3.4.0-rc1", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@storybook/addon-essentials": "^8.6.11", + "@storybook/addon-interactions": "^8.6.11", + "@storybook/addon-links": "^8.6.11", + "@storybook/addon-onboarding": "^8.6.11", + "@storybook/blocks": "^8.6.11", + "@storybook/react": "^8.6.11", + "@storybook/react-vite": "^8.6.11", + "@storybook/testing-library": "^0.2.2", + "@types/react": "^19.0.12", + "@types/react-dom": "^19.0.4", + "@vitejs/plugin-react": "^4.3.4", + "eslint": "^9.23.0", + "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "eslint-plugin-storybook": "^0.12.0", + "prop-types": "^15.8.1", + "storybook": "^8.6.11", + "vite": "^6.2.4" + } +} diff --git a/src/wrappers/wrappers/react-wrapper/src/components/BackendProvider/BackendProvider.jsx b/src/wrappers/wrappers/react-wrapper/src/components/BackendProvider/BackendProvider.jsx new file mode 100644 index 0000000..db7a320 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/components/BackendProvider/BackendProvider.jsx @@ -0,0 +1,39 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {v4 as uuid} from 'uuid'; + + +/** + * Primary UI component for user interaction + */ +export const BackendProvider = ({ remoteEndpoint, ...props }) => { + const id = uuid(); + return React.createElement('elsa-backend-provider', { + ...props, + id: id, + "remote-endpoint": remoteEndpoint, + "api-key": props.apiKey, + "access-token": props.accessToken + }); +}; + +BackendProvider.propTypes = { + /** + * The remote backend URL. + */ + remoteEndpoint: PropTypes.string, + /** + * The API Key, if any. + */ + apiKey: PropTypes.string, + /** + * The access token, if any. + */ + accessToken: PropTypes.string, +}; + +BackendProvider.defaultProps = { + remoteEndpoint: null, + apiKey: null, + accessToken: null, +}; diff --git a/src/wrappers/wrappers/react-wrapper/src/components/WorkflowDefinitionEditor/WorkflowDefinitionEditor.jsx b/src/wrappers/wrappers/react-wrapper/src/components/WorkflowDefinitionEditor/WorkflowDefinitionEditor.jsx new file mode 100644 index 0000000..43f8978 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/components/WorkflowDefinitionEditor/WorkflowDefinitionEditor.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {v4 as uuid} from 'uuid'; +import {RemoteArgs} from "../../remote-args.js"; + + +/** + * Primary UI component for user interaction + */ +export const WorkflowDefinitionEditor = ({ definitionId, remoteEndpoint, apiKey, ...props }) => { + const id = uuid(); + return React.createElement('elsa-workflow-definition-editor', { ...props, id: id, "definition-id": definitionId, "remote-endpoint": remoteEndpoint, "api-key": apiKey }); +}; + +WorkflowDefinitionEditor.propTypes = { + /** + * The workflow definition ID. + */ + definitionId: PropTypes.string, + /** + * The remote backend URL. + */ + remoteEndpoint: PropTypes.string, + /** + * The API Key, if any. + */ + apiKey: PropTypes.string, + /** + * The access token, if any. + */ + accessToken: PropTypes.string, +}; + +WorkflowDefinitionEditor.defaultProps = { + definitionId: null, + remoteEndpoint: RemoteArgs.remoteEndpoint, + apiKey: RemoteArgs.apiKey, + accessToken: null, + +}; diff --git a/src/wrappers/wrappers/react-wrapper/src/components/WorkflowDefinitionList/WorkflowDefinitionList.jsx b/src/wrappers/wrappers/react-wrapper/src/components/WorkflowDefinitionList/WorkflowDefinitionList.jsx new file mode 100644 index 0000000..63ad6f1 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/components/WorkflowDefinitionList/WorkflowDefinitionList.jsx @@ -0,0 +1,46 @@ +import React, {useEffect} from 'react'; +import PropTypes from 'prop-types'; +import {v4 as uuid} from 'uuid'; +import {RemoteArgs} from "../../remote-args.js"; + +/** + * Primary UI component for user interaction + */ +export const WorkflowDefinitionList = (props) => { + const id = uuid(); + const { remoteEndpoint, apiKey } = props; + + useEffect(() => { + let element = document.getElementById(id); + element.editWorkflowDefinition = (definitionId) => { + props.onEditWorkflowDefinition(definitionId); + }; + }, [id, props]); // Dependency array includes what the effect depends on to run. + + return React.createElement('elsa-workflow-definition-list', { ...props, id: id, "remote-endpoint": remoteEndpoint, "api-key": apiKey }); +} + +WorkflowDefinitionList.propTypes = { + /** + * The remote backend URL. + */ + remoteEndpoint: PropTypes.string, + /** + * The API Key, if any. + */ + apiKey: PropTypes.string, + /** + * The access token, if any. + */ + accessToken: PropTypes.string, + /** + * The callback invoked when a workflow definition is edited. + */ + onEditWorkflowDefinition: PropTypes.func, +}; + +WorkflowDefinitionList.defaultProps = { + remoteEndpoint: RemoteArgs.remoteEndpoint, + apiKey: RemoteArgs.apiKey, + accessToken: null +}; diff --git a/src/wrappers/wrappers/react-wrapper/src/components/WorkflowInstanceList/WorkflowInstanceList.jsx b/src/wrappers/wrappers/react-wrapper/src/components/WorkflowInstanceList/WorkflowInstanceList.jsx new file mode 100644 index 0000000..e3f7f32 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/components/WorkflowInstanceList/WorkflowInstanceList.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {v4 as uuid} from 'uuid'; +import {RemoteArgs} from "../../remote-args.js"; + +/** + * Primary UI component for user interaction + */ +export const WorkflowInstanceList = ({ remoteEndpoint, apiKey, ...props }) => { + const id = uuid(); + return React.createElement('elsa-workflow-instance-list', { ...props, id: id, "remote-endpoint": remoteEndpoint, "api-key": apiKey }); +}; + +WorkflowInstanceList.propTypes = { + /** + * The remote backend URL. + */ + remoteEndpoint: PropTypes.string, + /** + * The API Key, if any. + */ + apiKey: PropTypes.string, + /** + * The access token, if any. + */ + accessToken: PropTypes.string, +}; + +WorkflowInstanceList.defaultProps = { + remoteEndpoint: RemoteArgs.remoteEndpoint, + apiKey: RemoteArgs.apiKey, + accessToken: null, + +}; diff --git a/src/wrappers/wrappers/react-wrapper/src/components/WorkflowInstanceViewer/WorkflowInstanceViewer.jsx b/src/wrappers/wrappers/react-wrapper/src/components/WorkflowInstanceViewer/WorkflowInstanceViewer.jsx new file mode 100644 index 0000000..899215b --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/components/WorkflowInstanceViewer/WorkflowInstanceViewer.jsx @@ -0,0 +1,39 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {v4 as uuid} from 'uuid'; +import {RemoteArgs} from "../../remote-args.js"; + +/** + * Primary UI component for user interaction + */ +export const WorkflowInstanceViewer = ({ instanceId, remoteEndpoint, apiKey, ...props }) => { + const id = uuid(); + return React.createElement('elsa-workflow-instance-viewer', { ...props, id: id, "instance-id": instanceId, "remote-endpoint": remoteEndpoint, "api-key": apiKey }); +}; + +WorkflowInstanceViewer.propTypes = { + /** + * The workflow definition ID. + */ + instanceId: PropTypes.string, + /** + * The remote backend URL. + */ + remoteEndpoint: PropTypes.string, + /** + * The API Key, if any. + */ + apiKey: PropTypes.string, + /** + * The access token, if any. + */ + accessToken: PropTypes.string, +}; + +WorkflowInstanceViewer.defaultProps = { + instanceId: null, + remoteEndpoint: RemoteArgs.remoteEndpoint, + apiKey: RemoteArgs.apiKey, + accessToken: null, + +}; diff --git a/src/wrappers/wrappers/react-wrapper/src/main.js b/src/wrappers/wrappers/react-wrapper/src/main.js new file mode 100644 index 0000000..0e61003 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/main.js @@ -0,0 +1,6 @@ +import {BackendProvider} from "./components/BackendProvider/BackendProvider.jsx"; +import {WorkflowDefinitionEditor} from "./components/WorkflowDefinitionEditor/WorkflowDefinitionEditor.jsx"; +import {WorkflowInstanceViewer} from "./components/WorkflowInstanceViewer/WorkflowInstanceViewer.jsx"; +import {WorkflowDefinitionList} from "./components/WorkflowDefinitionList/WorkflowDefinitionList.jsx"; + +export {BackendProvider, WorkflowDefinitionEditor, WorkflowInstanceViewer, WorkflowDefinitionList}; \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/src/remote-args.js b/src/wrappers/wrappers/react-wrapper/src/remote-args.js new file mode 100644 index 0000000..73cb45c --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/remote-args.js @@ -0,0 +1,4 @@ +export const RemoteArgs = { + remoteEndpoint: "https://localhost:5001/elsa/api", + apiKey: "48587230567A646D394B435A6277734A-4802fa49-e91e-45e8-b00f-b5492377e20b", +} \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/Configure.mdx b/src/wrappers/wrappers/react-wrapper/src/stories/Configure.mdx new file mode 100644 index 0000000..a50fcea --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/Configure.mdx @@ -0,0 +1,364 @@ +import { Meta } from "@storybook/blocks"; + +import Github from "./assets/github.svg"; +import Discord from "./assets/discord.svg"; +import Youtube from "./assets/youtube.svg"; +import Tutorials from "./assets/tutorials.svg"; +import Styling from "./assets/styling.png"; +import Context from "./assets/context.png"; +import Assets from "./assets/assets.png"; +import Docs from "./assets/docs.png"; +import Share from "./assets/share.png"; +import FigmaPlugin from "./assets/figma-plugin.png"; +import Testing from "./assets/testing.png"; +import Accessibility from "./assets/accessibility.png"; +import Theming from "./assets/theming.png"; +import AddonLibrary from "./assets/addon-library.png"; + +export const RightArrow = () => + + + + + +
+
+ # Configure your project + + Because Storybook works separately from your app, you'll need to configure it for your specific stack and setup. Below, explore guides for configuring Storybook with popular frameworks and tools. If you get stuck, learn how you can ask for help from our community. +
+
+
+ A wall of logos representing different styling technologies +

Add styling and CSS

+

Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.

+ Learn more +
+
+ An abstraction representing the composition of data for a component +

Provide context and mocking

+

Often when a story doesn't render, it's because your component is expecting a specific environment or context (like a theme provider) to be available.

+ Learn more +
+
+ A representation of typography and image assets +
+

Load assets and resources

+

To link static files (like fonts) to your projects and stories, use the + `staticDirs` configuration option to specify folders to load when + starting Storybook.

+ Learn more +
+
+
+
+
+
+ # Do more with Storybook + + Now that you know the basics, let's explore other parts of Storybook that will improve your experience. This list is just to get you started. You can customise Storybook in many ways to fit your needs. +
+ +
+
+
+ A screenshot showing the autodocs tag being set, pointing a docs page being generated +

Autodocs

+

Auto-generate living, + interactive reference documentation from your components and stories.

+ Learn more +
+
+ A browser window showing a Storybook being published to a chromatic.com URL +

Publish to Chromatic

+

Publish your Storybook to review and collaborate with your entire team.

+ Learn more +
+
+ Windows showing the Storybook plugin in Figma +

Figma Plugin

+

Embed your stories into Figma to cross-reference the design and live + implementation in one place.

+ Learn more +
+
+ Screenshot of tests passing and failing +

Testing

+

Use stories to test a component in all its variations, no matter how + complex.

+ Learn more +
+
+ Screenshot of accessibility tests passing and failing +

Accessibility

+

Automatically test your components for a11y issues as you develop.

+ Learn more +
+
+ Screenshot of Storybook in light and dark mode +

Theming

+

Theme Storybook's UI to personalize it to your project.

+ Learn more +
+
+
+
+
+
+

Addons

+

Integrate your tools with Storybook to connect workflows.

+ Discover all addons +
+
+ Integrate your tools with Storybook to connect workflows. +
+
+ +
+
+ Github logo + Join our contributors building the future of UI development. + + Star on GitHub +
+
+ Discord logo +
+ Get support and chat with frontend developers. + + Join Discord server +
+
+
+ Youtube logo +
+ Watch tutorials, feature previews and interviews. + + Watch on YouTube +
+
+
+ A book +

Follow guided walkthroughs on for key workflows.

+ + Discover tutorials +
+
+ + diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowDefinitionEditor.stories.js b/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowDefinitionEditor.stories.js new file mode 100644 index 0000000..f6e53b4 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowDefinitionEditor.stories.js @@ -0,0 +1,21 @@ +import {WorkflowDefinitionEditor} from "../components/WorkflowDefinitionEditor/WorkflowDefinitionEditor.jsx"; +import {RemoteArgs} from "../remote-args.js"; + +export default { + title: "Workflows/WorkflowDefinitionEditor", + component: WorkflowDefinitionEditor, + parameters: { + layout: "centered" + }, + argTypes: { + definitionId: { control: "text" } + } +}; + +export const Default = { + args: { + definitionId: "57305c33e237893b", + remoteEndpoint: RemoteArgs.remoteEndpoint, + apiKey: RemoteArgs.apiKey + } +} \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowDefinitionList.stories.js b/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowDefinitionList.stories.js new file mode 100644 index 0000000..657b610 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowDefinitionList.stories.js @@ -0,0 +1,20 @@ +import {WorkflowDefinitionList} from "../components/WorkflowDefinitionList/WorkflowDefinitionList.jsx"; +import {RemoteArgs} from "../remote-args.js"; + +export default { + title: "Workflows/WorkflowDefinitionList", + component: WorkflowDefinitionList, + parameters: { + layout: "centered" + }, + argTypes: { + definitionId: { control: "text" } + } +}; + +export const Default = { + args: { + remoteEndpoint: RemoteArgs.remoteEndpoint, + apiKey: RemoteArgs.apiKey + } +} \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowInstanceList.stories.js b/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowInstanceList.stories.js new file mode 100644 index 0000000..2eb8ee4 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowInstanceList.stories.js @@ -0,0 +1,20 @@ +import {WorkflowInstanceList} from "../components/WorkflowInstanceList/WorkflowInstanceList.jsx"; +import {RemoteArgs} from "../remote-args.js"; + +export default { + title: "Workflows/WorkflowInstanceList", + component: WorkflowInstanceList, + parameters: { + layout: "centered" + }, + argTypes: { + definitionId: { control: "text" } + } +}; + +export const Default = { + args: { + remoteEndpoint: RemoteArgs.remoteEndpoint, + apiKey: RemoteArgs.apiKey + } +} \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowInstanceViewer.stories.js b/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowInstanceViewer.stories.js new file mode 100644 index 0000000..a5a7c32 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/WorkflowInstanceViewer.stories.js @@ -0,0 +1,21 @@ +import { WorkflowInstanceViewer} from "../components/WorkflowInstanceViewer/WorkflowInstanceViewer.jsx"; +import {RemoteArgs} from "../remote-args.js"; + +export default { + title: "Workflows/WorkflowInstanceViewer", + component: WorkflowInstanceViewer, + parameters: { + layout: "centered" + }, + argTypes: { + definitionId: { control: "text" } + } +}; + +export const Default = { + args: { + instanceId: "f14afe24a2e6f7b1", + remoteEndpoint: RemoteArgs.remoteEndpoint, + apiKey: RemoteArgs.apiKey + } +} \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/accessibility.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/accessibility.png new file mode 100644 index 0000000..6ffe6fe Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/accessibility.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/accessibility.svg b/src/wrappers/wrappers/react-wrapper/src/stories/assets/accessibility.svg new file mode 100644 index 0000000..a328883 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/assets/accessibility.svg @@ -0,0 +1,5 @@ + + Accessibility + + + \ No newline at end of file diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/addon-library.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/addon-library.png new file mode 100644 index 0000000..95deb38 Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/addon-library.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/assets.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/assets.png new file mode 100644 index 0000000..cfba681 Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/assets.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/context.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/context.png new file mode 100644 index 0000000..e5cd249 Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/context.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/discord.svg b/src/wrappers/wrappers/react-wrapper/src/stories/assets/discord.svg new file mode 100644 index 0000000..1204df9 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/assets/discord.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/docs.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/docs.png new file mode 100644 index 0000000..a749629 Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/docs.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/figma-plugin.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/figma-plugin.png new file mode 100644 index 0000000..8f79b08 Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/figma-plugin.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/github.svg b/src/wrappers/wrappers/react-wrapper/src/stories/assets/github.svg new file mode 100644 index 0000000..158e026 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/assets/github.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/share.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/share.png new file mode 100644 index 0000000..8097a37 Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/share.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/styling.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/styling.png new file mode 100644 index 0000000..d341e82 Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/styling.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/testing.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/testing.png new file mode 100644 index 0000000..d4ac39a Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/testing.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/theming.png b/src/wrappers/wrappers/react-wrapper/src/stories/assets/theming.png new file mode 100644 index 0000000..1535eb9 Binary files /dev/null and b/src/wrappers/wrappers/react-wrapper/src/stories/assets/theming.png differ diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/tutorials.svg b/src/wrappers/wrappers/react-wrapper/src/stories/assets/tutorials.svg new file mode 100644 index 0000000..4b2fc7c --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/assets/tutorials.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/wrappers/wrappers/react-wrapper/src/stories/assets/youtube.svg b/src/wrappers/wrappers/react-wrapper/src/stories/assets/youtube.svg new file mode 100644 index 0000000..33a3a61 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/src/stories/assets/youtube.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/wrappers/wrappers/react-wrapper/vite.config.js b/src/wrappers/wrappers/react-wrapper/vite.config.js new file mode 100644 index 0000000..d8392c7 --- /dev/null +++ b/src/wrappers/wrappers/react-wrapper/vite.config.js @@ -0,0 +1,22 @@ +import { defineConfig } from 'vite' +import { resolve } from 'path' +import react from '@vitejs/plugin-react' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + build: { + lib: { + // Could also be a dictionary or array of multiple entry points + entry: resolve(__dirname, 'src/main.js'), + name: 'Elsa Studio WASM React Wrapper', + // the proper extensions will be added + fileName: 'elsa-studio-wasm-react', + }, + rollupOptions: { + // make sure to externalize deps that shouldn't be bundled + // into your library + external: ['react'], + }, + }, +})