diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..e8eb5f827c --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# Code owners must approve every pull request (see branch protection on develop and main). +* @yasmoradi @msynk diff --git a/.github/GITHUB_PROCESS.md b/.github/GITHUB_PROCESS.md deleted file mode 100644 index ef031d300c..0000000000 --- a/.github/GITHUB_PROCESS.md +++ /dev/null @@ -1,14 +0,0 @@ - -# Automatic conversation locking -Closed issues and pull requests are locked automatically after 30 days of inactivity. - -## I want to comment on a locked conversation, what should I do? -When an issue has been closed and inactive for over 30 days, the original context is likely outdated. -If you encounter a similar or related issue in the current version, please open a new issue and -provide up-to-date reproduction instructions. - -## Why lock conversations? -Automatically locking closed, inactive issues guides people towards filing new issues with updated -context rather than commenting on a "resolved" issue that contains out-of-date or unrelated -information. As an example, someone may comment "I'm still having this issue", but without -providing any of the additional information the team needs to investigate. \ No newline at end of file diff --git a/.github/agents/dependency-update.md b/.github/agents/dependency-update.md index c83fd2be79..49d623ce3f 100644 --- a/.github/agents/dependency-update.md +++ b/.github/agents/dependency-update.md @@ -17,7 +17,7 @@ Work the surfaces in this order. Each is independent; batch the network lookups. 3. GitHub Actions (`.github/workflows/`, `src/Templates/Boilerplate/Bit.Boilerplate/.github/workflows/`, `src/Butil/tests/Bit.Butil.Tests.E2E/ci/`) 4. Azure DevOps tasks (`src/Templates/Boilerplate/Bit.Boilerplate/.azure-devops/workflows/`) 5. devcontainers (`.devcontainer/`, `src/Templates/Boilerplate/Bit.Boilerplate/.devcontainer/`) -6. `.config/dotnet-tools.json` (4 files), `global.json` (3 files) +6. `dnx @` calls in workflows and docs (`vpk`, `dotnet-ef`), `global.json` (3 files) 7. Container image tags in the Aspire AppHost ## The hold-back rules @@ -57,7 +57,7 @@ consumes a test project, so every band takes the newest patch of its own band. L **Version ranges stay.** `[8.0.0,9.0.0)` is a compatibility contract, not a pin. -**`Bit.*` self-references track the in-development version**, currently `10.6.0`. Never read +**`Bit.*` self-references track the in-development version**, currently `10.6.1`. Never read these off nuget.org — the published `latest` is behind the working tree by design, and unrelated higher-numbered lines exist there. @@ -81,6 +81,20 @@ gh api "repos///git/trees/?recursive=1" --jq '[.tree[]|select( A non-zero count on a JavaScript action that vendors `node_modules` means it will not stage. This is worth checking for *any* action bump, not just this one — it is invisible in the release notes. +**MAUI is held at 10.0.100** (`Microsoft.Maui.Controls` and `Components.WebView.Maui`, in the +Boilerplate, the BlazorUI demo and the Butil sample). 10.0.101 bundles an `Svg.Skia` that calls a +SkiaSharp overload missing from the SkiaSharp next to it, so the resizetizer fails with `MAUIR0001` / +`MissingMethodException: SKImageFilter.CreateMatrixConvolution` on any SVG icon with a `` +([dotnet/maui#38319](https://github.com/dotnet/maui/issues/38319)). Move only once that issue is +closed and `dotnet build -f net10.0-ios` passes on the Boilerplate. `WebView.WindowsForms` has no +resizetizer and is not held. + +**`Xamarin.Firebase.Messaging` is held at 125.1.1.** 125.1.2 pulls `Xamarin.AndroidX.Fragment` 1.9.0 +(through `GooglePlayServices.Base` 118.10.1), which absorbed the ktx classes, while the rest of the +graph still brings `Fragment.Ktx` 1.8.9.x. R8 then fails the Android build with +`Type androidx.fragment.app.FragmentKt is defined multiple times`. Move it only once something else in +the graph already brings `Fragment.Ktx` 1.9.0 (an empty stub), rather than pinning Ktx in the template. + When a held pin's rationale no longer holds — the oldest supported SDK moved, TS 7 was adopted repo-wide — say so in the report rather than acting on it. @@ -149,8 +163,13 @@ Runner images (`runs-on`) are part of this: no `ubuntu-latest`, pin the concrete ### Azure DevOps -Tasks are major-versioned (`UseDotNet@2`, `FileTransform@2`). Confirm against Microsoft's task -reference; there is no API. All eight in use were current as of the last sweep. +Tasks are major-versioned (`UseDotNet@2`, `FileTransform@2`). The newest major is the highest +`V` folder in `gh api repos/microsoft/azure-pipelines-tasks/contents/Tasks --jq '.[].name'`. +A task can change name across majors while keeping its id: `NodeTool@1` resolves to `UseNodeV1`. + +`AzureRmWebAppDeployment` is on @4 while @5 exists. For `webAppLinux` @5 defaults to `oneDeploy` with +`CleanDeploymentFlag: true`, which deletes wwwroot files missing from the package — a deploy-behaviour +decision for the maintainer, not a routine bump. ### devcontainers @@ -167,11 +186,13 @@ The `image` follows the newest .NET SDK: `curl -s https://builds.dotnet.microsoft.com/dotnet/release-metadata/10.0/releases.json` → `.latest-sdk`. Both devcontainers must agree. -### dotnet-tools and global.json +### dnx tool versions and global.json -`vpk` must equal the `Velopack` PackageReference version in the same project — Velopack requires the -CLI and the library to match, and this has drifted before. `dotnet-ef` should equal the EF Core -package version. +There are no `.config/dotnet-tools.json` manifests any more: every tool is run with `dnx +@`, so the pins live in the workflow and doc lines that call them (`grep -rn "dnx +.*@"`). `vpk` must equal the `Velopack` PackageReference version in the same project — Velopack +requires the CLI and the library to match, and this has drifted before. `dotnet-ef` should equal the +EF Core package version. `src/global.json` is `rollForward: disable` and tracks the newest SDK. The two template `global.json` files are `10.0.100` + `latestFeature` deliberately — they must accept any 10.0.x on a @@ -228,3 +249,30 @@ different versions across projects. These are the ones worth a maintainer's atte - `npm install` in every directory whose `package.json` changed. - `dotnet build` the affected solutions; a Roslyn or MSBuild pin change needs a real build. - Never rewrite files through Python or `sed` — BOM and CRLF get clobbered. Use targeted edits. + +## Ship it + +Finish every sweep with an issue, a PR and a full CI run. `upstream` is `bitfoundation/bitplatform`, +`origin` is the maintainer's fork. + +1. Issue on upstream, label `dependencies`, title `Project dependencies are outdated`. The body + lists what is behind, in a sentence or two per surface. +2. Branch named after the issue number, cut from `upstream/develop`, not from whatever branch is + checked out. When the working tree sits on another branch, apply the diff in a worktree + (`git worktree add ../bitplatform- -b upstream/develop`, then `git diff | git apply --3way`) + so that branch and any build running on it stay untouched. +3. One commit, `feat(deps): update project dependencies #`. Push to `origin`. +4. PR from `:` into `upstream/develop`, title `Update project dependencies (#)`. + The body starts with `closes #` and carries the report: Changed, Breaking or important, + Held back, Missed / drifted, Not verified. +5. Run `all.ci.yml` on the fork against the branch and give its URL with the PR link: + + ```bash + gh workflow run all.ci.yml --repo /bitplatform --ref + gh run list --repo /bitplatform --workflow all.ci.yml --branch --limit 1 --json url --jq '.[0].url' + ``` + + A red job goes into the PR as a comment, with the failing step and its first error line. +6. Clean up at once, without asking: `git restore` the pushed files in the original checkout (after + `git diff -- ` comes back empty), delete build artifacts the sweep created, + and `git worktree remove` the worktree. `git status` must match what it was before the sweep. diff --git a/.github/lock.yml b/.github/lock.yml deleted file mode 100644 index 7b56be3bb4..0000000000 --- a/.github/lock.yml +++ /dev/null @@ -1,16 +0,0 @@ -daysUntilLock: 30 - -skipCreatedBefore: false - -# Issues and pull requests with these labels will be ignored. Set to `[]` to disable -exemptLabels: [] - -lockLabel: 'outdated' - -lockComment: > - This issue has been automatically locked due to inactivity. - Please file a new issue if you are encountering a similar or related problem. - - Read more about our [automatic conversation locking policy](https://github.com/bitfoundation/bitplatform/blob/main/.github/GITHUB_PROCESS.md). - -setLockReason: true diff --git a/.github/workflows/admin-sample.cd.yml b/.github/workflows/admin-sample.cd.yml index c066140ff3..f19e174a28 100644 --- a/.github/workflows/admin-sample.cd.yml +++ b/.github/workflows/admin-sample.cd.yml @@ -85,8 +85,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd AdminPanel - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -116,7 +115,15 @@ jobs: dotnet build AdminPanel/src/Client/AdminPanel.Client.Web/AdminPanel.Client.Web.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APP_VERSION}}" --no-restore -c Release - name: Publish Server Web - run: dotnet publish AdminPanel/src/Server/AdminPanel.Server.Web/AdminPanel.Server.Web.csproj -c Release -o server-web -p:Version="${{ vars.APP_VERSION}}" -p:AspNetCoreHostingModel=OutOfProcess + run: dotnet publish AdminPanel/src/Server/AdminPanel.Server.Web/AdminPanel.Server.Web.csproj -c Release -o server-web -p:Version="${{ vars.APP_VERSION}}" -p:AspNetCoreHostingModel=OutOfProcess -p:BitMinifyAggressive=true -p:BitMinifyMapOutputPath="${{ github.workspace }}/bit-minifier.map" + + # Every publish renames afresh, so this map reads the stack traces of this release and of no other. It lives in + # obj, which this checkout throws away - kept here, and never next to the client, which would serve it. + - name: Upload minifier map artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: AdminPanel-minifier-map + path: bit-minifier.map - name: Publish Server API run: dotnet publish AdminPanel/src/Server/AdminPanel.Server.Api/AdminPanel.Server.Api.csproj -c Release -o server-api -p:Version="${{ vars.APP_VERSION}}" -p:AspNetCoreHostingModel=OutOfProcess @@ -245,7 +252,14 @@ jobs: run: dotnet build AdminPanel/src/Client/AdminPanel.Client.Core/AdminPanel.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APP_VERSION}}" -p:WasmEnableSIMD=true --no-restore -c Release - name: Publish - run: dotnet publish AdminPanel/src/Client/AdminPanel.Client.Web/AdminPanel.Client.Web.csproj -c Release -o client -p:WasmEnableSIMD=true -p:Version="${{ vars.APP_VERSION}}" + run: dotnet publish AdminPanel/src/Client/AdminPanel.Client.Web/AdminPanel.Client.Web.csproj -c Release -o client -p:WasmEnableSIMD=true -p:Version="${{ vars.APP_VERSION}}" -p:BitMinifyAggressive=true -p:BitMinifyMapOutputPath="${{ github.workspace }}/bit-minifier.map" + + # what the stack traces this client logs are read back through: see the note in the server web job + - name: Upload minifier map artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: AdminPanelClient-minifier-map + path: bit-minifier.map - name: Upload to asw run: | @@ -283,8 +297,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd AdminPanel - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -305,21 +318,19 @@ jobs: continue-on-error: true run: | cd AdminPanel\src\Client\AdminPanel.Client.Windows\ - dotnet tool restore - dotnet vpk download s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases + dnx vpk@1.2.0 -- download s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases - name: Publish run: | cd AdminPanel\src\Client\AdminPanel.Client.Windows\ dotnet publish AdminPanel.Client.Windows.csproj -c Release -o .\publish-result -r win-x64 -p:Version="${{ vars.APP_VERSION}}" -p:PublishReadyToRun=true -p:PublishReadyToRunComposite=true --self-contained - dotnet tool restore - dotnet vpk pack -u AdminPanel.Client.Windows -v "${{ vars.APP_VERSION }}" -p .\publish-result -e AdminPanel.Client.Windows.exe -r win-x64 --framework webview2 --icon .\wwwroot\favicon.ico --packTitle 'AdminPanel' + dnx vpk@1.2.0 -- pack -u AdminPanel.Client.Windows -v "${{ vars.APP_VERSION }}" -p .\publish-result -e AdminPanel.Client.Windows.exe -r win-x64 --framework webview2 --icon .\wwwroot\favicon.ico --packTitle 'AdminPanel' # The update feed behind WindowsUpdate.FilesUrl. - name: Upload releases to R2 run: | cd AdminPanel\src\Client\AdminPanel.Client.Windows\ - dotnet vpk upload s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases --keepMaxReleases 10 + dnx vpk@1.2.0 -- upload s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases --keepMaxReleases 10 build_blazor_hybrid_android: name: build blazor hybrid (android) @@ -366,8 +377,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd AdminPanel - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -445,8 +455,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd AdminPanel - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -489,7 +498,7 @@ jobs: # App Store submission stays manual. - name: Upload to TestFlight - uses: apple-actions/upload-testflight-build@5e75ff58276689011512ba87a381d93dc67dbcf8 # v5.3.0 + uses: apple-actions/upload-testflight-build@1fc69ca369a60b813eaaa2d936eda22794b52e17 # v5.4.0 with: app-path: ${{ steps.ipa.outputs.path }} app-type: ios diff --git a/.github/workflows/all.ci.yml b/.github/workflows/all.ci.yml index 387a3ce79d..43d9229213 100644 --- a/.github/workflows/all.ci.yml +++ b/.github/workflows/all.ci.yml @@ -2,6 +2,55 @@ name: All CI on: workflow_dispatch: + inputs: + boilerplate: + description: Boilerplate solution + type: boolean + default: true + boilerplate_postgres: + description: Boilerplate tests with PostgreSQL + type: boolean + default: true + boilerplate_mssql: + description: Boilerplate tests with SQL Server + type: boolean + default: true + boilerplate_configurations: + description: Boilerplate configurations + type: boolean + default: true + blazorempty: + description: BlazorEmpty configurations + type: boolean + default: true + nuget_packages: + description: NuGet packages + type: boolean + default: true + bswup: + description: Bswup solution + type: boolean + default: true + butil: + description: Butil solution + type: boolean + default: true + brouter: + description: Brouter solution + type: boolean + default: true + bmotion: + description: Bmotion solution + type: boolean + default: true + tooling: + description: CodeAnalyzers, ResxTranslator and SourceGenerators solutions + type: boolean + default: true + websites: + description: Website solutions + type: boolean + default: true env: DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true @@ -16,6 +65,7 @@ jobs: build_boilerplate: name: build boilerplate itself + if: ${{ inputs.boilerplate }} runs-on: ubuntu-24.04 steps: @@ -46,6 +96,7 @@ jobs: test_boilerplate_postgres: name: create project from template with postgresql and test it + if: ${{ inputs.boilerplate_postgres }} runs-on: ubuntu-24.04 steps: @@ -87,8 +138,7 @@ jobs: run: | cd TestPostgreSQL/src/Server/TestPostgreSQL.Server.Api/ dotnet build -p:EnforceCodeStyleInBuild=true - dotnet tool restore - dotnet ef migrations add Initial --verbose + dnx dotnet-ef@10.0.12 -- migrations add Initial --verbose - name: Trust dotnet cert continue-on-error: true @@ -155,6 +205,7 @@ jobs: test_boilerplate_mssql: name: create project from template with sql server and test it + if: ${{ inputs.boilerplate_mssql }} runs-on: ubuntu-24.04 steps: @@ -196,8 +247,7 @@ jobs: run: | cd TestSqlServer/src/Server/TestSqlServer.Server.Api/ dotnet build -p:EnforceCodeStyleInBuild=true - dotnet tool restore - dotnet ef migrations add Initial --verbose + dnx dotnet-ef@10.0.12 -- migrations add Initial --verbose - name: Install sql server uses: potatoqualitee/mssqlsuite@2291d923e83859edd871679c05b379037376761f # v1.12 @@ -259,6 +309,7 @@ jobs: build_boilerplate_configurations: name: create several projects from template and build them + if: ${{ inputs.boilerplate_configurations }} runs-on: ubuntu-24.04 steps: @@ -327,6 +378,7 @@ jobs: build_blazorempty_configurations: name: build blazorempty based projects + if: ${{ inputs.blazorempty }} runs-on: ubuntu-24.04 steps: @@ -367,6 +419,7 @@ jobs: build_nuget_packages: name: build nuget packages locally + if: ${{ inputs.nuget_packages }} runs-on: ubuntu-24.04 steps: @@ -502,6 +555,13 @@ jobs: dotnet build src/CodeAnalyzers/Bit.CodeAnalyzers/Bit.CodeAnalyzers.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false dotnet pack src/CodeAnalyzers/Bit.CodeAnalyzers/Bit.CodeAnalyzers.csproj --output ./packages --configuration Release + - name: Build and pack Minifier + run: | + dotnet build src/Minifier/Bit.Minifier/Bit.Minifier.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false + dotnet pack src/Minifier/Bit.Minifier/Bit.Minifier.csproj --output ./packages --configuration Release + dotnet build src/Minifier/Bit.Minifier.Cli/Bit.Minifier.Cli.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false + dotnet pack src/Minifier/Bit.Minifier.Cli/Bit.Minifier.Cli.csproj --output ./packages --configuration Release + - name: Build and pack ResxTranslator run: | dotnet build src/ResxTranslator/Bit.ResxTranslator/Bit.ResxTranslator.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false @@ -527,6 +587,7 @@ jobs: build_bswup_solution: name: build bswup solution + if: ${{ inputs.bswup }} runs-on: ubuntu-24.04 steps: @@ -557,6 +618,7 @@ jobs: build_butil_solution: name: build butil solution + if: ${{ inputs.butil }} runs-on: ubuntu-24.04 steps: @@ -587,6 +649,7 @@ jobs: build_brouter_solution: name: build brouter solution + if: ${{ inputs.brouter }} runs-on: ubuntu-24.04 steps: @@ -617,6 +680,7 @@ jobs: build_bmotion_solution: name: build bmotion solution + if: ${{ inputs.bmotion }} runs-on: ubuntu-24.04 steps: @@ -647,6 +711,7 @@ jobs: build_tooling_solutions: name: build tooling solutions + if: ${{ inputs.tooling }} runs-on: ubuntu-24.04 steps: @@ -663,6 +728,12 @@ jobs: - name: Build CodeAnalyzers solution in Release mode run: dotnet build src/CodeAnalyzers/Bit.CodeAnalyzers.slnx -c Release + - name: Build Minifier solution in Release mode + run: dotnet build src/Minifier/Bit.Minifier.slnx -c Release + + - name: Test Minifier + run: cd src/Minifier && dotnet test --project Tests/Bit.Minifier.Tests/Bit.Minifier.Tests.csproj -c Release --no-build + - name: Build ResxTranslator solution in Release mode run: dotnet build src/ResxTranslator/Bit.ResxTranslator.slnx -c Release @@ -673,6 +744,7 @@ jobs: build_websites: name: build website solutions + if: ${{ inputs.websites }} runs-on: ubuntu-24.04 steps: diff --git a/.github/workflows/bit.ci.BlazorUI.yml b/.github/workflows/bit.ci.BlazorUI.yml index 8e6db8670d..49dd1da4ee 100644 --- a/.github/workflows/bit.ci.BlazorUI.yml +++ b/.github/workflows/bit.ci.BlazorUI.yml @@ -5,6 +5,7 @@ on: pull_request: paths: - 'src/BlazorUI/**' + - 'src/Minifier/**' env: DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true diff --git a/.github/workflows/bit.ci.Brouter.e2e.yml b/.github/workflows/bit.ci.Brouter.e2e.yml new file mode 100644 index 0000000000..cca46dda8b --- /dev/null +++ b/.github/workflows/bit.ci.Brouter.e2e.yml @@ -0,0 +1,208 @@ +name: bit platform CI - Brouter E2E + +# Browser, hybrid and publish-gate coverage for Bit.Brouter, next to the unit/hosting tests in +# bit.ci.Brouter.yml. See src/Brouter/Tests/Bit.Brouter.Tests.E2E/README.md for what each job proves +# and how to run the same thing locally. + +on: + workflow_dispatch: + pull_request: + paths: + - 'src/Brouter/**' + - '.github/workflows/bit.ci.Brouter.e2e.yml' + +env: + DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true + +permissions: + contents: read + +jobs: + + # Every web render mode (static SSR, Server, WebAssembly, Auto, with and without prerendering) in + # Chromium, on each runtime the library ships for. + e2e-web: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: Brouter E2E - web render modes (${{ matrix.framework }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + framework: [ net10.0, net9.0, net8.0 ] + + steps: + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + dotnet-version: 9.0.x + + - name: Setup .NET 8.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + dotnet-version: 8.0.x + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + - name: Build the web harness host + run: dotnet build src/Brouter/Tests/Bit.Brouter.Tests.Harness.Web/Bit.Brouter.Tests.Harness.Web.csproj -c Release -f ${{ matrix.framework }} + + - name: Build the E2E suite + run: dotnet build src/Brouter/Tests/Bit.Brouter.Tests.E2E/Bit.Brouter.Tests.E2E.csproj -c Release + + - name: Install Playwright Chromium + run: pwsh src/Brouter/Tests/Bit.Brouter.Tests.E2E/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + + - name: Run E2E tests + env: + BROUTER_E2E_FRAMEWORK: ${{ matrix.framework }} + BROUTER_E2E_CONFIGURATION: Release + BROUTER_E2E_SKIP_BUILD: 1 + # Run from inside src so src/global.json's Microsoft.Testing.Platform runner setting applies. + run: > + cd src/Brouter && + dotnet test --project Tests/Bit.Brouter.Tests.E2E/Bit.Brouter.Tests.E2E.csproj -c Release --no-build + --filter "FullyQualifiedName!~HybridModeTests" + --report-trx --report-trx-filename brouter-e2e-web-${{ matrix.framework }}.trx + + - name: Upload test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: brouter-e2e-web-${{ matrix.framework }} + path: '**/brouter-e2e-web-*.trx' + if-no-files-found: ignore + + # Blazor Hybrid: the harness in a WinForms BlazorWebView, driven through WebView2's DevTools port. + e2e-hybrid: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: Brouter E2E - Blazor Hybrid (WebView2) + runs-on: windows-2025 + + steps: + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + # windows-2025 ships the Edge browser but not the WebView2 Runtime, which BlazorWebView needs. + - name: Install the WebView2 Runtime + shell: pwsh + run: | + $clientKey = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' + $version = (Get-ItemProperty $clientKey -ErrorAction SilentlyContinue).pv + if (-not $version -or $version -eq '0.0.0.0') { + $installer = Join-Path $env:RUNNER_TEMP 'MicrosoftEdgeWebview2Setup.exe' + Invoke-WebRequest 'https://go.microsoft.com/fwlink/p/?LinkId=2124703' -OutFile $installer + Start-Process $installer -ArgumentList '/silent', '/install' -Wait + $version = (Get-ItemProperty $clientKey -ErrorAction SilentlyContinue).pv + } + if (-not $version -or $version -eq '0.0.0.0') { throw 'The WebView2 Runtime did not install.' } + Write-Host "WebView2 Runtime $version" + + - name: Build the hybrid harness host + run: dotnet build src/Brouter/Tests/Bit.Brouter.Tests.Harness.Hybrid/Bit.Brouter.Tests.Harness.Hybrid.csproj -c Release + + - name: Build the E2E suite + run: dotnet build src/Brouter/Tests/Bit.Brouter.Tests.E2E/Bit.Brouter.Tests.E2E.csproj -c Release + + # No Playwright browser download: it attaches to the WebView2 Runtime installed above. + - name: Run hybrid E2E tests + env: + BROUTER_E2E_CONFIGURATION: Release + BROUTER_E2E_SKIP_BUILD: 1 + run: > + cd src/Brouter && + dotnet test --project Tests/Bit.Brouter.Tests.E2E/Bit.Brouter.Tests.E2E.csproj -c Release --no-build + --filter "FullyQualifiedName~HybridModeTests" + --report-trx --report-trx-filename brouter-e2e-hybrid.trx + + - name: Upload test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: brouter-e2e-hybrid + path: '**/brouter-e2e-hybrid.trx' + if-no-files-found: ignore + + # Publishes the harness the way a WebAssembly app ships - trimmed, and in a second leg AOT-compiled - + # failing on any trim analysis warning, then runs the browser suite against that published output. + # Trimming is where reflection-based parameter binding, route discovery and the prerender state + # bridge break, and none of it is visible in a Debug build. + publish-gate: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: Brouter publish gate (${{ matrix.name }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - name: trimmed + properties: '' + - name: aot + properties: '-p:RunAOTCompilation=true' + + steps: + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + - name: Install wasm-tools + if: matrix.name == 'aot' + run: dotnet workload install wasm-tools + + - name: Publish the web harness host (fails on trim/AOT warnings from Bit.Brouter) + run: bash src/Brouter/Tests/Bit.Brouter.Tests.E2E/publish-gate.sh ${{ github.workspace }}/artifacts/harness-${{ matrix.name }} ${{ matrix.properties }} + + - name: Build the E2E suite + run: dotnet build src/Brouter/Tests/Bit.Brouter.Tests.E2E/Bit.Brouter.Tests.E2E.csproj -c Release + + - name: Install Playwright Chromium + run: pwsh src/Brouter/Tests/Bit.Brouter.Tests.E2E/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + + - name: Run E2E tests against the published host + env: + BROUTER_E2E_PUBLISHED_HOST: ${{ github.workspace }}/artifacts/harness-${{ matrix.name }} + run: > + cd src/Brouter && + dotnet test --project Tests/Bit.Brouter.Tests.E2E/Bit.Brouter.Tests.E2E.csproj -c Release --no-build + --filter "FullyQualifiedName!~HybridModeTests" + --report-trx --report-trx-filename brouter-publish-${{ matrix.name }}.trx + + - name: Upload test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: brouter-publish-${{ matrix.name }} + path: '**/brouter-publish-*.trx' + if-no-files-found: ignore diff --git a/.github/workflows/bit.ci.Brouter.yml b/.github/workflows/bit.ci.Brouter.yml index 29ceffb441..586055cbaa 100644 --- a/.github/workflows/bit.ci.Brouter.yml +++ b/.github/workflows/bit.ci.Brouter.yml @@ -61,3 +61,10 @@ jobs: # Run from inside src so src/global.json's "test" runner setting applies # (from the repo root the SDK falls back to the unsupported VSTest path). run: cd src/Brouter && dotnet test Tests/Bit.Brouter.Tests.Mcp/Bit.Brouter.Tests.Mcp.csproj --no-build + + - name: dotnet test (source generator) + run: cd src/Brouter && dotnet test Tests/Bit.Brouter.Tests.Generators/Bit.Brouter.Tests.Generators.csproj --no-build + + - name: dotnet test (hosting - every render mode over HTTP, net8.0/net9.0/net10.0) + # Browser, hybrid and trimmed/AOT publish coverage runs in bit.ci.Brouter.e2e.yml. + run: cd src/Brouter && dotnet test Tests/Bit.Brouter.Tests.Hosting/Bit.Brouter.Tests.Hosting.csproj --no-build diff --git a/.github/workflows/bit.ci.Bswup.e2e.yml b/.github/workflows/bit.ci.Bswup.e2e.yml new file mode 100644 index 0000000000..040d641702 --- /dev/null +++ b/.github/workflows/bit.ci.Bswup.e2e.yml @@ -0,0 +1,138 @@ +name: bit platform CI - Bswup E2E + +# Real-browser and publish-gate coverage for Bit.Bswup, next to the build, hosting and JS unit tests in +# bit.ci.Bswup.yml. See src/Bswup/Tests/Bit.Bswup.Tests.E2E/README.md for what each job proves and how to +# run the same thing locally. + +on: + workflow_dispatch: + pull_request: + paths: + - 'src/Bswup/**' + - '.github/workflows/bit.ci.Bswup.e2e.yml' + +env: + DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true + +permissions: + contents: read + +jobs: + + # Every host shape (the Blazor Web App in the WebAssembly, WebAssembly without prerendering, Auto and Server + # render modes, and the standalone WebAssembly app on a sub-path) in Chromium, on each runtime the library + # ships for. + e2e-web: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: Bswup E2E - browser (${{ matrix.framework }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + framework: [ net10.0, net9.0, net8.0 ] + + steps: + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + dotnet-version: 9.0.x + + - name: Setup .NET 8.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + dotnet-version: 8.0.x + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + - name: Build the harness host + run: dotnet build src/Bswup/Tests/Bit.Bswup.Tests.Harness.Web/Bit.Bswup.Tests.Harness.Web.csproj -c Release -f ${{ matrix.framework }} + + - name: Build the E2E suite + run: dotnet build src/Bswup/Tests/Bit.Bswup.Tests.E2E/Bit.Bswup.Tests.E2E.csproj -c Release + + - name: Install Playwright Chromium + run: pwsh src/Bswup/Tests/Bit.Bswup.Tests.E2E/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + + - name: Run E2E tests + env: + BSWUP_E2E_FRAMEWORK: ${{ matrix.framework }} + BSWUP_E2E_CONFIGURATION: Release + BSWUP_E2E_SKIP_BUILD: 1 + # Run from inside src so src/global.json's Microsoft.Testing.Platform runner setting applies. + run: > + cd src/Bswup && + dotnet test --project Tests/Bit.Bswup.Tests.E2E/Bit.Bswup.Tests.E2E.csproj -c Release --no-build + --report-trx --report-trx-filename bswup-e2e-web-${{ matrix.framework }}.trx + + - name: Upload test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: bswup-e2e-web-${{ matrix.framework }} + path: '**/bswup-e2e-web-*.trx' + if-no-files-found: ignore + + # Publishes the harness the way an app ships - trimmed WebAssembly clients, pre-compressed static assets, + # the service-worker manifests generated for publish - and runs the browser suite against that output. The + # integrity-checked install is the test that matters most here: it proves the published bytes match the + # hashes the published manifest carries, which a Debug build never shows. + publish-gate: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: Bswup publish gate + runs-on: ubuntu-24.04 + + steps: + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + # TargetFrameworks=net10.0 on top of -f: -f alone does not reach project references, which then still + # evaluate (and, without their SDKs installed, fail on) every framework they target. + - name: Publish the harness host + run: > + dotnet publish src/Bswup/Tests/Bit.Bswup.Tests.Harness.Web/Bit.Bswup.Tests.Harness.Web.csproj + -c Release -f net10.0 -p:TargetFrameworks=net10.0 -o ${{ github.workspace }}/artifacts/bswup-harness + + - name: Build the E2E suite + run: dotnet build src/Bswup/Tests/Bit.Bswup.Tests.E2E/Bit.Bswup.Tests.E2E.csproj -c Release + + - name: Install Playwright Chromium + run: pwsh src/Bswup/Tests/Bit.Bswup.Tests.E2E/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + + - name: Run E2E tests against the published host + env: + BSWUP_E2E_PUBLISHED_HOST: ${{ github.workspace }}/artifacts/bswup-harness + run: > + cd src/Bswup && + dotnet test --project Tests/Bit.Bswup.Tests.E2E/Bit.Bswup.Tests.E2E.csproj -c Release --no-build + --report-trx --report-trx-filename bswup-publish.trx + + - name: Upload test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: bswup-publish + path: '**/bswup-publish.trx' + if-no-files-found: ignore diff --git a/.github/workflows/bit.ci.Bswup.yml b/.github/workflows/bit.ci.Bswup.yml index 2a4daf237a..aef06ea2c0 100644 --- a/.github/workflows/bit.ci.Bswup.yml +++ b/.github/workflows/bit.ci.Bswup.yml @@ -63,6 +63,10 @@ jobs: - name: dotnet test (MCP server) run: cd src/Bswup && dotnet test Tests/Bit.Bswup.Tests.Mcp/Bit.Bswup.Tests.Mcp.csproj -f net10.0 --no-build + - name: dotnet test (hosting - served assets, host documents and BswupProgress over HTTP, net8.0/net9.0/net10.0) + # Real-browser coverage (install, offline, updates, recovery) and the published-output gate run in bit.ci.Bswup.e2e.yml. + run: cd src/Bswup && dotnet test Tests/Bit.Bswup.Tests.Hosting/Bit.Bswup.Tests.Hosting.csproj --no-build + # Runs against Bit.Bswup/wwwroot/*.js, which the build above produces, so this also covers # the build step itself (e.g. the minifier re-introducing downleveled syntax). - name: JS tests (service worker, page script, progress UI) diff --git a/.github/workflows/bit.ci.Butil.e2e.yml b/.github/workflows/bit.ci.Butil.e2e.yml new file mode 100644 index 0000000000..7dec73a117 --- /dev/null +++ b/.github/workflows/bit.ci.Butil.e2e.yml @@ -0,0 +1,222 @@ +name: bit platform CI - Butil E2E + +# Browser, hybrid and publish-gate coverage for Bit.Butil, next to the build, MCP and hosting tests in +# bit.ci.Butil.yml. Every job runs the same E2E suite against a different host (BUTIL_E2E_HOST); see +# src/Butil/tests/Bit.Butil.Tests.E2E/README.md for what each host proves and how to run the same thing locally. + +on: + workflow_dispatch: + pull_request: + paths: + - 'src/Butil/**' + - '.github/workflows/bit.ci.Butil.e2e.yml' + +env: + DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true + +permissions: + contents: read + +jobs: + + # The standalone WebAssembly sample, and every render mode of the Blazor Web App harness host (with and without + # prerendering) in Chromium - on every runtime the library ships for where the runtime is what differs. + e2e-web: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: Butil E2E - ${{ matrix.host }} (${{ matrix.framework }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - { host: standalone, framework: net10.0 } + - { host: server, framework: net10.0 } + - { host: server-noprerender, framework: net10.0 } + - { host: wasm, framework: net10.0 } + - { host: wasm-noprerender, framework: net10.0 } + - { host: auto, framework: net10.0 } + - { host: auto-noprerender, framework: net10.0 } + - { host: server, framework: net9.0 } + - { host: wasm, framework: net9.0 } + - { host: server, framework: net8.0 } + - { host: wasm, framework: net8.0 } + + steps: + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + dotnet-version: 9.0.x + + - name: Setup .NET 8.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + dotnet-version: 8.0.x + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + # The standalone sample is started with `dotnet run`, which builds it; the web harness host is built here. + - name: Build the web harness host + if: matrix.host != 'standalone' + run: dotnet build src/Butil/tests/Bit.Butil.Tests.Harness.Web/Bit.Butil.Tests.Harness.Web.csproj -c Release -f ${{ matrix.framework }} + + - name: Build the E2E suite + run: dotnet build src/Butil/tests/Bit.Butil.Tests.E2E/Bit.Butil.Tests.E2E.csproj -c Release + + - name: Install Playwright Chromium + run: pwsh src/Butil/tests/Bit.Butil.Tests.E2E/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + + - name: Run E2E tests + env: + BUTIL_E2E_HOST: ${{ matrix.host }} + BUTIL_E2E_FRAMEWORK: ${{ matrix.framework }} + BUTIL_E2E_CONFIGURATION: Release + BUTIL_E2E_SKIP_BUILD: 1 + # Run from inside src so src/global.json's Microsoft.Testing.Platform runner setting applies. + run: > + cd src/Butil && + dotnet test --project tests/Bit.Butil.Tests.E2E/Bit.Butil.Tests.E2E.csproj -c Release --no-build + --report-trx --report-trx-filename butil-e2e-${{ matrix.host }}-${{ matrix.framework }}.trx + + - name: Upload test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: butil-e2e-${{ matrix.host }}-${{ matrix.framework }} + path: '**/butil-e2e-*.trx' + if-no-files-found: ignore + + # Blazor Hybrid: the harness pages in a WinForms BlazorWebView, driven through WebView2's DevTools port. + e2e-hybrid: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: Butil E2E - hybrid (WebView2) + runs-on: windows-2025 + + steps: + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + # windows-2025 ships the Edge browser but not the WebView2 Runtime, which BlazorWebView needs. + - name: Install the WebView2 Runtime + shell: pwsh + run: | + $clientKey = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' + $version = (Get-ItemProperty $clientKey -ErrorAction SilentlyContinue).pv + if (-not $version -or $version -eq '0.0.0.0') { + $installer = Join-Path $env:RUNNER_TEMP 'MicrosoftEdgeWebview2Setup.exe' + Invoke-WebRequest 'https://go.microsoft.com/fwlink/p/?LinkId=2124703' -OutFile $installer + Start-Process $installer -ArgumentList '/silent', '/install' -Wait + $version = (Get-ItemProperty $clientKey -ErrorAction SilentlyContinue).pv + } + if (-not $version -or $version -eq '0.0.0.0') { throw 'The WebView2 Runtime did not install.' } + Write-Host "WebView2 Runtime $version" + + - name: Build the hybrid harness host + run: dotnet build src/Butil/tests/Bit.Butil.Tests.Harness.Hybrid/Bit.Butil.Tests.Harness.Hybrid.csproj -c Release + + - name: Build the E2E suite + run: dotnet build src/Butil/tests/Bit.Butil.Tests.E2E/Bit.Butil.Tests.E2E.csproj -c Release + + # No Playwright browser download: the suite attaches to the WebView2 Runtime installed above. + - name: Run hybrid E2E tests + env: + BUTIL_E2E_HOST: hybrid + BUTIL_E2E_CONFIGURATION: Release + BUTIL_E2E_SKIP_BUILD: 1 + run: > + cd src/Butil && + dotnet test --project tests/Bit.Butil.Tests.E2E/Bit.Butil.Tests.E2E.csproj -c Release --no-build + --report-trx --report-trx-filename butil-e2e-hybrid.trx + + - name: Upload test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: butil-e2e-hybrid + path: '**/butil-e2e-hybrid.trx' + if-no-files-found: ignore + + # Publishes the Web App harness host the way an app ships - its WebAssembly client trimmed, and in a second leg + # AOT-compiled, with the JavaScript bundle trimmed by the reference scan - failing on any trim analysis warning + # from Bit.Butil, then runs the browser suite against that output in the WebAssembly render mode. Trimming is + # where a DTO System.Text.Json reflects over, a DI constructor or a JavaScript module goes missing, and none of + # it is visible in a Debug build. + publish-gate: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: Butil publish gate (${{ matrix.name }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - name: trimmed + properties: '' + - name: aot + properties: '-p:RunAOTCompilation=true' + + steps: + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24 + + - name: Install wasm-tools + if: matrix.name == 'aot' + run: dotnet workload install wasm-tools + + - name: Publish the web harness host (fails on trim/AOT warnings from Bit.Butil) + run: bash src/Butil/tests/Bit.Butil.Tests.E2E/publish-gate.sh ${{ github.workspace }}/artifacts/butil-harness-${{ matrix.name }} ${{ matrix.properties }} + + - name: Build the E2E suite + run: dotnet build src/Butil/tests/Bit.Butil.Tests.E2E/Bit.Butil.Tests.E2E.csproj -c Release + + - name: Install Playwright Chromium + run: pwsh src/Butil/tests/Bit.Butil.Tests.E2E/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + + - name: Run E2E tests against the published host + env: + BUTIL_E2E_HOST: wasm + BUTIL_E2E_PUBLISHED_HOST: ${{ github.workspace }}/artifacts/butil-harness-${{ matrix.name }} + run: > + cd src/Butil && + dotnet test --project tests/Bit.Butil.Tests.E2E/Bit.Butil.Tests.E2E.csproj -c Release --no-build + --report-trx --report-trx-filename butil-publish-${{ matrix.name }}.trx + + - name: Upload test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: butil-publish-${{ matrix.name }} + path: '**/butil-publish-*.trx' + if-no-files-found: ignore diff --git a/.github/workflows/bit.ci.Butil.yml b/.github/workflows/bit.ci.Butil.yml index 1c3bf57ba2..186d2fdc16 100644 --- a/.github/workflows/bit.ci.Butil.yml +++ b/.github/workflows/bit.ci.Butil.yml @@ -81,3 +81,21 @@ jobs: name: butil-mcp-results path: '**/butil-mcp.trx' if-no-files-found: ignore + + # Every render mode of the Blazor Web App harness host over HTTP, on net8.0/net9.0/net10.0: the prerendered + # pages, the served scripts, and every member of every service called during a static render. Browser, hybrid + # and trimmed/AOT publish coverage runs in bit.ci.Butil.e2e.yml. + - name: Hosting tests + run: > + cd src/Butil && + dotnet test tests/Bit.Butil.Tests.Hosting/Bit.Butil.Tests.Hosting.csproj + --no-build + --report-trx --report-trx-filename butil-hosting.trx + + - name: Upload hosting test results + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: butil-hosting-results + path: '**/butil-hosting*.trx' + if-no-files-found: ignore diff --git a/.github/workflows/bit.ci.Minifier.yml b/.github/workflows/bit.ci.Minifier.yml new file mode 100644 index 0000000000..b53b64d54d --- /dev/null +++ b/.github/workflows/bit.ci.Minifier.yml @@ -0,0 +1,37 @@ +name: bit platform CI - Minifier + +on: + workflow_dispatch: + pull_request: + paths: + - 'src/Minifier/**' + +env: + DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true + +permissions: + contents: read + +jobs: + build-Minifier: + if: startsWith(github.event.pull_request.title, 'Prerelease') != true && startsWith(github.event.pull_request.title, 'Release') != true && startsWith(github.event.pull_request.title, 'Version') != true + name: build Bit.Minifier + runs-on: ubuntu-24.04 + + steps: + + - name: Checkout source code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup .NET 10.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: src/global.json + + - name: dotnet build + run: dotnet build src/Minifier/Bit.Minifier.slnx + + - name: dotnet test + run: cd src/Minifier && dotnet test --project Tests/Bit.Minifier.Tests/Bit.Minifier.Tests.csproj --no-build diff --git a/.github/workflows/bit.ci.Templates.yml b/.github/workflows/bit.ci.Templates.yml index 512fa75344..d602809bd0 100644 --- a/.github/workflows/bit.ci.Templates.yml +++ b/.github/workflows/bit.ci.Templates.yml @@ -5,6 +5,7 @@ on: pull_request: paths: - 'src/Templates/**' + - 'src/Minifier/**' env: DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true diff --git a/.github/workflows/bit.ci.Websites.yml b/.github/workflows/bit.ci.Websites.yml index 464115552b..c0f8bc27ee 100644 --- a/.github/workflows/bit.ci.Websites.yml +++ b/.github/workflows/bit.ci.Websites.yml @@ -5,6 +5,7 @@ on: pull_request: paths: - 'src/Websites/**' + - 'src/Minifier/**' env: DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true diff --git a/.github/workflows/blazorui.demo.cd.yml b/.github/workflows/blazorui.demo.cd.yml index 4c37255640..a621273456 100644 --- a/.github/workflows/blazorui.demo.cd.yml +++ b/.github/workflows/blazorui.demo.cd.yml @@ -164,21 +164,19 @@ jobs: continue-on-error: true run: | cd src\BlazorUI\Demo\Client\Bit.BlazorUI.Demo.Client.Windows\ - dotnet tool restore - dotnet vpk download s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases + dnx vpk@1.2.0 -- download s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases - name: Publish run: | cd src\BlazorUI\Demo\Client\Bit.BlazorUI.Demo.Client.Windows\ dotnet publish Bit.BlazorUI.Demo.Client.Windows.csproj -c Release -o .\publish-result -r win-x86 -p:Version="${{ vars.APP_VERSION}}" -p:CompressionEnabled=false -p:PublishReadyToRun=true -p:PublishReadyToRunComposite=true --self-contained - dotnet tool restore - dotnet vpk pack -u Bit.BlazorUI.Demo.Client.Windows -v "${{ vars.APP_VERSION }}" -p .\publish-result -e Bit.BlazorUI.Demo.Client.Windows.exe -r win-x86 --framework webview2 --icon .\wwwroot\favicon.ico --packTitle 'Bit Blazor UI' + dnx vpk@1.2.0 -- pack -u Bit.BlazorUI.Demo.Client.Windows -v "${{ vars.APP_VERSION }}" -p .\publish-result -e Bit.BlazorUI.Demo.Client.Windows.exe -r win-x86 --framework webview2 --icon .\wwwroot\favicon.ico --packTitle 'Bit Blazor UI' # The update feed behind WindowsUpdateSettings.FilesUrl. - name: Upload releases to R2 run: | cd src\BlazorUI\Demo\Client\Bit.BlazorUI.Demo.Client.Windows\ - dotnet vpk upload s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases --keepMaxReleases 10 + dnx vpk@1.2.0 -- upload s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases --keepMaxReleases 10 build_blazor_hybrid_android: @@ -307,7 +305,7 @@ jobs: # App Store submission stays manual. - name: Upload to TestFlight - uses: apple-actions/upload-testflight-build@5e75ff58276689011512ba87a381d93dc67dbcf8 # v5.3.0 + uses: apple-actions/upload-testflight-build@1fc69ca369a60b813eaaa2d936eda22794b52e17 # v5.4.0 with: app-path: ${{ steps.ipa.outputs.path }} app-type: ios diff --git a/.github/workflows/nuget.org.yml b/.github/workflows/nuget.org.yml index be26208267..3a5be637d6 100644 --- a/.github/workflows/nuget.org.yml +++ b/.github/workflows/nuget.org.yml @@ -12,6 +12,7 @@ on: - 'src/Bswup/**' - 'src/Butil/**' - 'src/CodeAnalyzers/**' + - 'src/Minifier/**' - 'src/SourceGenerators/**' - 'src/Templates/**' @@ -161,6 +162,16 @@ jobs: - name: dotnet pack CodeAnalyzer run: dotnet pack src/CodeAnalyzers/Bit.CodeAnalyzers/Bit.CodeAnalyzers.csproj --output . --configuration Release + - name: dotnet build Minifier + run: dotnet build src/Minifier/Bit.Minifier/Bit.Minifier.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false + - name: dotnet pack Minifier + run: dotnet pack src/Minifier/Bit.Minifier/Bit.Minifier.csproj --output . --configuration Release + + - name: dotnet build Minifier.Cli + run: dotnet build src/Minifier/Bit.Minifier.Cli/Bit.Minifier.Cli.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false + - name: dotnet pack Minifier.Cli + run: dotnet pack src/Minifier/Bit.Minifier.Cli/Bit.Minifier.Cli.csproj --output . --configuration Release + - name: dotnet build ResxTranslator run: dotnet build src/ResxTranslator/Bit.ResxTranslator/Bit.ResxTranslator.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack ResxTranslator diff --git a/.github/workflows/platform.website.cd.yml b/.github/workflows/platform.website.cd.yml index ee44705f12..77bf840d4e 100644 --- a/.github/workflows/platform.website.cd.yml +++ b/.github/workflows/platform.website.cd.yml @@ -35,7 +35,15 @@ jobs: run: dotnet build src/Websites/Platform/src/Bit.Websites.Platform.Client/Bit.Websites.Platform.Client.csproj -t:BeforeBuildTasks -c Release -p:Version="${{ vars.APP_VERSION}}" - name: Publish - run: dotnet publish src/Websites/Platform/src/Bit.Websites.Platform.Server/Bit.Websites.Platform.Server.csproj -c Release -o server -p:Version="${{ vars.APP_VERSION}}" + run: dotnet publish src/Websites/Platform/src/Bit.Websites.Platform.Server/Bit.Websites.Platform.Server.csproj -c Release -o server -p:Version="${{ vars.APP_VERSION}}" -p:BitMinifyMapOutputPath="${{ github.workspace }}/bit-minifier.map" + + # Every publish renames afresh, so this map reads the stack traces of this release and of no other. It lives in + # obj, which this checkout throws away - kept here, and never next to the client, which would serve it. + - name: Upload minifier map artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: PlatformWebsite-minifier-map + path: bit-minifier.map # Server-owned; C:\inetpub keeps its own copies. - name: Strip server-owned files from bundle diff --git a/.github/workflows/prerelease.nuget.org.yml b/.github/workflows/prerelease.nuget.org.yml index 8deb654d82..2a46aa0452 100644 --- a/.github/workflows/prerelease.nuget.org.yml +++ b/.github/workflows/prerelease.nuget.org.yml @@ -150,6 +150,16 @@ jobs: - name: dotnet pack CodeAnalyzer run: dotnet pack src/CodeAnalyzers/Bit.CodeAnalyzers/Bit.CodeAnalyzers.csproj --output . --configuration Release + - name: dotnet build Minifier + run: dotnet build src/Minifier/Bit.Minifier/Bit.Minifier.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false + - name: dotnet pack Minifier + run: dotnet pack src/Minifier/Bit.Minifier/Bit.Minifier.csproj --output . --configuration Release + + - name: dotnet build Minifier.Cli + run: dotnet build src/Minifier/Bit.Minifier.Cli/Bit.Minifier.Cli.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false + - name: dotnet pack Minifier.Cli + run: dotnet pack src/Minifier/Bit.Minifier.Cli/Bit.Minifier.Cli.csproj --output . --configuration Release + - name: dotnet build ResxTranslator run: dotnet build src/ResxTranslator/Bit.ResxTranslator/Bit.ResxTranslator.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack ResxTranslator diff --git a/.github/workflows/sales-module-demo.cd.yml b/.github/workflows/sales-module-demo.cd.yml index 3c9c434a08..0d0855d67b 100644 --- a/.github/workflows/sales-module-demo.cd.yml +++ b/.github/workflows/sales-module-demo.cd.yml @@ -91,7 +91,15 @@ jobs: dotnet build SalesModule/src/Client/SalesModule.Client.Web/SalesModule.Client.Web.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APP_VERSION}}" --no-restore -c Release - name: Publish - run: dotnet publish SalesModule/src/Server/SalesModule.Server.Web/SalesModule.Server.Web.csproj -c Release -o server -p:Version="${{ vars.APP_VERSION}}" -p:AspNetCoreHostingModel=OutOfProcess + run: dotnet publish SalesModule/src/Server/SalesModule.Server.Web/SalesModule.Server.Web.csproj -c Release -o server -p:Version="${{ vars.APP_VERSION}}" -p:AspNetCoreHostingModel=OutOfProcess -p:BitMinifyAggressive=true -p:BitMinifyMapOutputPath="${{ github.workspace }}/bit-minifier.map" + + # Every publish renames afresh, so this map reads the stack traces of this release and of no other. It lives in + # obj, which this checkout throws away - kept here, and never next to the client, which would serve it. + - name: Upload minifier map artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: SalesModule-minifier-map + path: bit-minifier.map # Server-owned; C:\inetpub keeps its own copies. Also keeps them out of the artifact. - name: Strip server-owned files from bundle @@ -177,8 +185,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd SalesModule - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Generate CSS/JS files run: dotnet build SalesModule\src\Client\SalesModule.Client.Core\SalesModule.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APP_VERSION}}" --no-restore -c Release @@ -188,18 +195,16 @@ jobs: continue-on-error: true run: | cd SalesModule\src\Client\SalesModule.Client.Windows\ - dotnet tool restore - dotnet vpk download s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases + dnx vpk@1.2.0 -- download s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases - name: Publish run: | cd SalesModule\src\Client\SalesModule.Client.Windows\ dotnet publish SalesModule.Client.Windows.csproj -c Release -o .\publish-result -r win-x64 -p:Version="${{ vars.APP_VERSION}}" -p:PublishReadyToRun=true -p:PublishReadyToRunComposite=true --self-contained - dotnet tool restore - dotnet vpk pack -u SalesModule.Client.Windows -v "${{ vars.APP_VERSION }}" -p .\publish-result -e SalesModule.Client.Windows.exe -r win-x64 --framework webview2 --icon .\wwwroot\favicon.ico --packTitle 'SalesModule' + dnx vpk@1.2.0 -- pack -u SalesModule.Client.Windows -v "${{ vars.APP_VERSION }}" -p .\publish-result -e SalesModule.Client.Windows.exe -r win-x64 --framework webview2 --icon .\wwwroot\favicon.ico --packTitle 'SalesModule' # The update feed behind WindowsUpdate.FilesUrl. - name: Upload releases to R2 run: | cd SalesModule\src\Client\SalesModule.Client.Windows\ - dotnet vpk upload s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases --keepMaxReleases 10 + dnx vpk@1.2.0 -- upload s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases --keepMaxReleases 10 diff --git a/.github/workflows/sales.website.cd.yml b/.github/workflows/sales.website.cd.yml index 7b7534189e..89c40aa1f7 100644 --- a/.github/workflows/sales.website.cd.yml +++ b/.github/workflows/sales.website.cd.yml @@ -35,7 +35,15 @@ jobs: run: dotnet build src/Websites/Sales/src/Bit.Websites.Sales.Client/Bit.Websites.Sales.Client.csproj -t:BeforeBuildTasks --no-restore -c Release -p:Version="${{ vars.APP_VERSION}}" - name: Publish - run: dotnet publish src/Websites/Sales/src/Bit.Websites.Sales.Server/Bit.Websites.Sales.Server.csproj -c Release -o server -p:Version="${{ vars.APP_VERSION}}" + run: dotnet publish src/Websites/Sales/src/Bit.Websites.Sales.Server/Bit.Websites.Sales.Server.csproj -c Release -o server -p:Version="${{ vars.APP_VERSION}}" -p:BitMinifyMapOutputPath="${{ github.workspace }}/bit-minifier.map" + + # Every publish renames afresh, so this map reads the stack traces of this release and of no other. It lives in + # obj, which this checkout throws away - kept here, and never next to the client, which would serve it. + - name: Upload minifier map artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: SalesWebsite-minifier-map + path: bit-minifier.map # Server-owned; C:\inetpub keeps its own copies. - name: Strip server-owned files from bundle diff --git a/.github/workflows/todo-sample.cd.yml b/.github/workflows/todo-sample.cd.yml index a02f8f1566..b74e378ffa 100644 --- a/.github/workflows/todo-sample.cd.yml +++ b/.github/workflows/todo-sample.cd.yml @@ -88,8 +88,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd TodoSample - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -149,8 +148,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd TodoSample - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -177,7 +175,15 @@ jobs: dotnet build TodoSample/src/Client/TodoSample.Client.Web/TodoSample.Client.Web.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APP_VERSION}}" --no-restore -c Release - name: Publish Server Web - run: dotnet publish TodoSample/src/Server/TodoSample.Server.Web/TodoSample.Server.Web.csproj -c Release -o server-web -p:Version="${{ vars.APP_VERSION}}" -p:AspNetCoreHostingModel=OutOfProcess + run: dotnet publish TodoSample/src/Server/TodoSample.Server.Web/TodoSample.Server.Web.csproj -c Release -o server-web -p:Version="${{ vars.APP_VERSION}}" -p:AspNetCoreHostingModel=OutOfProcess -p:BitMinifyAggressive=true -p:BitMinifyMapOutputPath="${{ github.workspace }}/bit-minifier.map" + + # Every publish renames afresh, so this map reads the stack traces of this release and of no other. It lives in + # obj, which this checkout throws away - kept here, and never next to the client, which would serve it. + - name: Upload minifier map artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: Todo-minifier-map + path: bit-minifier.map # Server-owned; C:\inetpub keeps its own copies. Also keeps them out of the artifact. - name: Strip server-owned files from bundle @@ -293,7 +299,14 @@ jobs: run: dotnet build TodoSample/src/Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APP_VERSION}}" -p:WasmEnableSIMD=true --no-restore -c Release - name: Publish - run: dotnet publish TodoSample/src/Client/TodoSample.Client.Web/TodoSample.Client.Web.csproj -c Release -o client -p:Version="${{ vars.APP_VERSION}}" -p:RunAOTCompilation=true -p:InvariantGlobalization=true -p:WasmEnableSIMD=true + run: dotnet publish TodoSample/src/Client/TodoSample.Client.Web/TodoSample.Client.Web.csproj -c Release -o client -p:Version="${{ vars.APP_VERSION}}" -p:RunAOTCompilation=true -p:InvariantGlobalization=true -p:WasmEnableSIMD=true -p:BitMinifyAggressive=true -p:BitMinifyMapOutputPath="${{ github.workspace }}/bit-minifier.map" + + # what the stack traces this client logs are read back through: see the note in the server web job + - name: Upload minifier map artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: TodoAot-minifier-map + path: bit-minifier.map - name: Upload to asw run: | @@ -347,7 +360,7 @@ jobs: - name: Optimize DbContext run: | - cd TodoSample/src/Server/TodoSample.Server.Web && dotnet tool restore && dotnet build -c Release && dotnet ef dbcontext optimize --context AppOfflineDbContext --output-dir Infrastructure/Data/CompiledModel --namespace TodoSample.Client.Core.Infrastructure.Data --project ../../Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj --verbose + cd TodoSample/src/Server/TodoSample.Server.Web && dotnet build -c Release && dnx dotnet-ef@10.0.12 -- dbcontext optimize --context AppOfflineDbContext --output-dir Infrastructure/Data/CompiledModel --namespace TodoSample.Client.Core.Infrastructure.Data --project ../../Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj --verbose - name: Publish run: dotnet publish TodoSample/src/Client/TodoSample.Client.Web/TodoSample.Client.Web.csproj -c Release -o client -p:Version="${{ vars.APP_VERSION}}" -p:WasmEnableSIMD=true -p:InvariantGlobalization=true @@ -399,9 +412,16 @@ jobs: - name: Generate CSS/JS files run: dotnet build TodoSample/src/Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj -t:BeforeBuildTasks -p:WasmEnableSIMD=true -p:Version="${{ vars.APP_VERSION}}" --no-restore -c Release - + - name: Publish - run: dotnet publish TodoSample/src/Client/TodoSample.Client.Web/TodoSample.Client.Web.csproj -c Release -o client -p:Version="${{ vars.APP_VERSION}}" -p:WasmEnableSIMD=true -p:InvariantGlobalization=true + run: dotnet publish TodoSample/src/Client/TodoSample.Client.Web/TodoSample.Client.Web.csproj -c Release -o client -p:Version="${{ vars.APP_VERSION}}" -p:WasmEnableSIMD=true -p:InvariantGlobalization=true -p:BitMinifyAggressive=true -p:BitMinifyMapOutputPath="${{ github.workspace }}/bit-minifier.map" + + # what the stack traces this client logs are read back through: see the note in the server web job + - name: Upload minifier map artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: TodoSmall-minifier-map + path: bit-minifier.map - name: Upload to asw run: | @@ -439,8 +459,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd TodoSample - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -461,21 +480,19 @@ jobs: continue-on-error: true run: | cd TodoSample\src\Client\TodoSample.Client.Windows\ - dotnet tool restore - dotnet vpk download s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases + dnx vpk@1.2.0 -- download s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases - name: Publish run: | cd TodoSample\src\Client\TodoSample.Client.Windows\ dotnet publish TodoSample.Client.Windows.csproj -c Release -o .\publish-result -r win-x86 -p:Version="${{ vars.APP_VERSION}}" - dotnet tool restore - dotnet vpk pack -u TodoSample.Client.Windows -v "${{ vars.APP_VERSION }}" -p .\publish-result -e TodoSample.Client.Windows.exe -r win-x86 --framework webview2 --icon .\wwwroot\favicon.ico --packTitle TodoSample + dnx vpk@1.2.0 -- pack -u TodoSample.Client.Windows -v "${{ vars.APP_VERSION }}" -p .\publish-result -e TodoSample.Client.Windows.exe -r win-x86 --framework webview2 --icon .\wwwroot\favicon.ico --packTitle TodoSample # The update feed behind WindowsUpdate.FilesUrl. - name: Upload releases to R2 run: | cd TodoSample\src\Client\TodoSample.Client.Windows\ - dotnet vpk upload s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases --keepMaxReleases 10 + dnx vpk@1.2.0 -- upload s3 --endpoint ${{ vars.R2_ENDPOINT }} --bucket ${{ env.R2_BUCKET }} --keyId ${{ secrets.R2_ACCESS_KEY_ID }} --secret ${{ secrets.R2_SECRET_ACCESS_KEY }} -o .\Releases --keepMaxReleases 10 build_blazor_hybrid_android: @@ -523,8 +540,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd TodoSample - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -623,8 +639,7 @@ jobs: - name: Use Bit.ResxTranslator run: | cd TodoSample - dotnet tool install --global Bit.ResxTranslator --prerelease - bit-resx-translate + dnx Bit.ResxTranslator --prerelease - name: Update core appsettings.json uses: devops-actions/variable-substitution@ae7b1f3676ae374dc70282e6b9650bc50b611222 # v1.2 @@ -687,7 +702,7 @@ jobs: # App Store submission stays manual. - name: Upload to TestFlight - uses: apple-actions/upload-testflight-build@5e75ff58276689011512ba87a381d93dc67dbcf8 # v5.3.0 + uses: apple-actions/upload-testflight-build@1fc69ca369a60b813eaaa2d936eda22794b52e17 # v5.4.0 with: app-path: ${{ steps.ipa.outputs.path }} app-type: ios diff --git a/src/Besql/Bit.Besql/wwwroot/bit-besql.js b/src/Besql/Bit.Besql/wwwroot/bit-besql.js index fa959a338e..c40108a287 100644 --- a/src/Besql/Bit.Besql/wwwroot/bit-besql.js +++ b/src/Besql/Bit.Besql/wwwroot/bit-besql.js @@ -1,5 +1,5 @@ var BitBesql = window.BitBesql || {}; -BitBesql.version = window['bit-besql version'] = '10.6.0'; +BitBesql.version = window['bit-besql version'] = '10.6.1'; BitBesql.persist = async function besqlPersist(fileName) { diff --git a/src/Bit.Build.props b/src/Bit.Build.props index 1e2f6e054f..fb566f2b2c 100644 --- a/src/Bit.Build.props +++ b/src/Bit.Build.props @@ -27,7 +27,7 @@ https://github.com/bitfoundation/bitplatform - 10.6.0 + 10.6.1 $(ReleaseVersion) https://github.com/bitfoundation/bitplatform/releases/tag/v-$(ReleaseVersion) $([System.String]::Copy($(ReleaseVersion)).Replace('-pre-', '.')) diff --git a/src/Bit.CI.Release.slnx b/src/Bit.CI.Release.slnx index 57bc4ce8ad..8ca78dde3a 100644 --- a/src/Bit.CI.Release.slnx +++ b/src/Bit.CI.Release.slnx @@ -93,6 +93,10 @@ + + + + diff --git a/src/Bit.slnx b/src/Bit.slnx index b9f8b0921b..0f29362c47 100644 --- a/src/Bit.slnx +++ b/src/Bit.slnx @@ -94,6 +94,14 @@ + + + + + + + + @@ -131,6 +139,14 @@ + + + + + + + + @@ -150,13 +166,29 @@ + + + + + + + + + + + + + + + + diff --git a/src/BlazorES2019/Bit.BlazorES2019/buildTransitive/Bit.BlazorES2019.targets b/src/BlazorES2019/Bit.BlazorES2019/buildTransitive/Bit.BlazorES2019.targets index 9524f5d2d8..dcc337a334 100644 --- a/src/BlazorES2019/Bit.BlazorES2019/buildTransitive/Bit.BlazorES2019.targets +++ b/src/BlazorES2019/Bit.BlazorES2019/buildTransitive/Bit.BlazorES2019.targets @@ -1,13 +1,13 @@ - - + + PreserveNewest PreserveNewest wwwroot\_framework\%(Filename)%(Extension) - - + + PreserveNewest PreserveNewest wwwroot\_framework\%(Filename)%(Extension) diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/Scripts/generate-flags.py b/src/BlazorUI/Bit.BlazorUI.Assets/Scripts/generate-flags.py new file mode 100644 index 0000000000..145e8393f8 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Assets/Scripts/generate-flags.py @@ -0,0 +1,176 @@ +""" +Generates the country flag image sets of Bit.BlazorUI.Assets, and the boxes BitFlag cuts a shaped frame +to, out of one folder of source png images. + + python -m pip install pillow + python Bit.BlazorUI.Assets/Scripts/generate-flags.py + +The source folder holds one folder per ISO 3166-1 alpha-2 code, each carrying the ten images +flat-16.png ... flat-64.png and shiny-16.png ... shiny-64.png. A folder missing any of them is skipped, +and the codes left have to be exactly the ones the packaged 16 pixel images of Bit.BlazorUI.Extras +cover - which are the countries of BitCountries.All - or nothing is written. + +What it writes: + + - Bit.BlazorUI.Assets/wwwroot/flags/--.webp, replacing whatever was there. The flat + set is lossless: its artwork is flat color, where lossless WebP is both smaller and exact. The shiny + set is lossy at quality 90 with a lossless alpha channel: its gradients are what lossy WebP is for, + at about half the size of lossless. + - Bit.BlazorUI.Extras/Components/Flag/BitFlag.razor.boxes.cs, the box every image draws its flag in. +""" + +import argparse +import os +import sys +from collections import Counter + +from PIL import Image + +SETS = ("flat", "shiny") +SIZES = (16, 24, 32, 48, 64) + +# A pixel counts as part of the flag once it is at least half opaque, so the faint edge the artwork +# antialiases a flag with is left outside the box rather than rounded, bordered and shadowed. +OPAQUE = 128 + +HERE = os.path.dirname(os.path.abspath(__file__)) +BLAZORUI = os.path.normpath(os.path.join(HERE, "..", "..")) +ASSETS_FLAGS = os.path.join(BLAZORUI, "Bit.BlazorUI.Assets", "wwwroot", "flags") +EXTRAS_FLAGS = os.path.join(BLAZORUI, "Bit.BlazorUI.Extras", "wwwroot", "flags") +BOXES_FILE = os.path.join(BLAZORUI, "Bit.BlazorUI.Extras", "Components", "Flag", "BitFlag.razor.boxes.cs") +EXTRAS_SUFFIX = "-flat-16.webp" + + +def source_codes(source): + codes, skipped = [], [] + for code in sorted(os.listdir(source)): + folder = os.path.join(source, code) + if os.path.isdir(folder) is False: + continue + if all(os.path.isfile(os.path.join(folder, f"{s}-{z}.png")) for s in SETS for z in SIZES): + codes.append(code.upper()) + else: + skipped.append(code) + return codes, skipped + + +def content_box(image): + mask = image.getchannel("A").point(lambda a: 255 if a >= OPAQUE else 0) + left, top, right, bottom = mask.getbbox() + return (left, top, right - left, bottom - top) + + +def encode(image, set_name, path): + if set_name == "flat": + image.save(path, "WEBP", lossless=True, quality=100, method=6, exact=True) + else: + image.save(path, "WEBP", quality=90, alpha_quality=100, method=6) + + # The flat set has to come back exactly as it went in, and the shiny set with the alpha channel the + # boxes are measured on: a box that no longer matches the pixels drawn would cut the flag wrong. + with Image.open(path) as written: + written = written.convert("RGBA") + if set_name == "flat": + if written.tobytes() != image.tobytes(): + sys.exit(f"{path} did not round-trip losslessly") + elif content_box(written) != content_box(image): + sys.exit(f"{path} does not keep the content box of its source") + + +def write_boxes(boxes): + lines = [ + "// ", + "// GENERATED by Bit.BlazorUI.Assets/Scripts/generate-flags.py, together with the flag images of", + "// Bit.BlazorUI.Assets/wwwroot/flags. Regenerate with that script, never by hand.", + "// ", + "", + "#nullable enable", + "", + "namespace Bit.BlazorUI;", + "", + "public partial class BitFlag", + "{", + " /// ", + " /// The pixel sizes every image set of the Bit.BlazorUI.Assets package draws each flag at, smallest first.", + " /// ", + f" private static readonly int[] FlagImageSizes = [{', '.join(str(z) for z in SIZES)}];", + "", + " /// ", + " /// The box a flag image draws its flag in, in the pixels of that image.", + " /// ", + " /// ", + " /// Every image is square, with the flag drawn in its own proportions and transparent space around it.", + " /// The box is the bounds of the pixels that are at least half opaque, so the faint edge the artwork", + " /// antialiases a flag with stays outside it. Nearly every flag of a set shares one box per size, and the", + " /// few drawn in other proportions carry their own. The boxes of one flag are not a scaling of each", + " /// other - the small sizes are snapped to whole pixels - which is why every size has its own. The", + " /// packaged image of the Extras package is the 16 pixel image of the flat set.", + " /// ", + " private static FlagBox GetFlagContentBox(BitFlagImageSet set, int size, string? iso2) => (set, size, iso2) switch", + " {", + ] + + for set_name in SETS: + enum = f"BitFlagImageSet.{set_name.capitalize()}" + for size in SIZES: + per_code = boxes[(set_name, size)] + default, _ = sorted(Counter(per_code.values()).items(), key=lambda kv: (-kv[1], kv[0]))[0] + for code in sorted(per_code): + if per_code[code] != default: + x, y, w, h = per_code[code] + lines.append(f" ({enum}, {size}, \"{code}\") => new({x}, {y}, {w}, {h}),") + x, y, w, h = default + lines.append(f" ({enum}, {size}, _) => new({x}, {y}, {w}, {h}),") + + lines += [ + " _ => new(0, 0, size, size),", + " };", + "}", + "", + ] + + # The encoding and line endings every C# source of the repository is checked out with. + with open(BOXES_FILE, "w", encoding="utf-8-sig", newline="\r\n") as file: + file.write("\n".join(lines)) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("source", help="the folder of per-country folders of source png images") + source = parser.parse_args().source + + codes, skipped = source_codes(source) + extras = sorted(f[: -len(EXTRAS_SUFFIX)].upper() for f in os.listdir(EXTRAS_FLAGS) if f.endswith(EXTRAS_SUFFIX)) + if codes != extras: + missing = sorted(set(extras) - set(codes)) + extra = sorted(set(codes) - set(extras)) + sys.exit(f"The source covers other countries than the packaged flags do. Missing: {missing}. Not packaged: {extra}.") + + os.makedirs(ASSETS_FLAGS, exist_ok=True) + for name in os.listdir(ASSETS_FLAGS): + if name.endswith(".webp"): + os.remove(os.path.join(ASSETS_FLAGS, name)) + + boxes = {(s, z): {} for s in SETS for z in SIZES} + total = 0 + for code in codes: + for set_name in SETS: + for size in SIZES: + with Image.open(os.path.join(source, code, f"{set_name}-{size}.png")) as png: + image = png.convert("RGBA") + if image.size != (size, size): + sys.exit(f"{code}/{set_name}-{size}.png is {image.size[0]}x{image.size[1]} rather than {size}x{size}") + path = os.path.join(ASSETS_FLAGS, f"{code}-{set_name}-{size}.webp") + encode(image, set_name, path) + total += os.path.getsize(path) + boxes[(set_name, size)][code] = content_box(image) + + write_boxes(boxes) + + print(f"{len(codes)} countries, {len(codes) * len(SETS) * len(SIZES)} images, {total / 1024:.0f} KB") + if skipped: + print(f"Skipped incomplete source folders: {', '.join(skipped)}") + + +if __name__ == "__main__": + main() diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/package-lock.json b/src/BlazorUI/Bit.BlazorUI.Assets/package-lock.json index b17b211923..7b420965df 100644 --- a/src/BlazorUI/Bit.BlazorUI.Assets/package-lock.json +++ b/src/BlazorUI/Bit.BlazorUI.Assets/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "devDependencies": { - "sass": "1.104.0" + "sass": "1.104.1" } }, "node_modules/@parcel/watcher": { @@ -448,9 +448,9 @@ } }, "node_modules/sass": { - "version": "1.104.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.104.0.tgz", - "integrity": "sha512-btHMApW2bgolvClhRW8AlQJzgI9lUB3pPSofBQQT+E46GWvf9o0TVQ13SYv5riWZVFyPN+JNz3TKW9XhBlc10w==", + "version": "1.104.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.104.1.tgz", + "integrity": "sha512-yDA+1aIG3EHgN4V/BvuhCvu61FF6hEd4e+9DxikUm9U0CAGuvdIZ/UYy7qbOxjhbbWQraoyLlMuzdRGOSV5Bmw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/package.json b/src/BlazorUI/Bit.BlazorUI.Assets/package.json index 0ae9591972..0f9cdedea8 100644 --- a/src/BlazorUI/Bit.BlazorUI.Assets/package.json +++ b/src/BlazorUI/Bit.BlazorUI.Assets/package.json @@ -1,5 +1,5 @@ { "devDependencies": { - "sass": "1.104.0" + "sass": "1.104.1" } } diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-16.webp new file mode 100644 index 0000000000..e3b3621f98 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-24.webp new file mode 100644 index 0000000000..d14b1522d5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-32.webp new file mode 100644 index 0000000000..c7147f2ff1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-48.webp new file mode 100644 index 0000000000..6d7afb54a8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-64.webp new file mode 100644 index 0000000000..56b813c932 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-16.webp new file mode 100644 index 0000000000..c3c2560b04 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-24.webp new file mode 100644 index 0000000000..8a48fe4c1e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-32.webp new file mode 100644 index 0000000000..37371fd000 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-48.webp new file mode 100644 index 0000000000..32df2c60b0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-64.webp new file mode 100644 index 0000000000..618d3f848d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AD-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-16.webp new file mode 100644 index 0000000000..67627d30ae Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-24.webp new file mode 100644 index 0000000000..67d4119a12 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-32.webp new file mode 100644 index 0000000000..cbcd18fdaf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-48.webp new file mode 100644 index 0000000000..76aa39a0f9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-64.webp new file mode 100644 index 0000000000..3be58e2da2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-16.webp new file mode 100644 index 0000000000..72020de135 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-24.webp new file mode 100644 index 0000000000..662e0c21e5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-32.webp new file mode 100644 index 0000000000..07d0b18b9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-48.webp new file mode 100644 index 0000000000..4fe9277dc3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-64.webp new file mode 100644 index 0000000000..ffde66a6af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-16.webp new file mode 100644 index 0000000000..0f7ea60486 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-24.webp new file mode 100644 index 0000000000..b107c006e9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-32.webp new file mode 100644 index 0000000000..08c72e2402 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-48.webp new file mode 100644 index 0000000000..2a24d5c3a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-64.webp new file mode 100644 index 0000000000..3d6969e844 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-16.webp new file mode 100644 index 0000000000..e3fcee284f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-24.webp new file mode 100644 index 0000000000..39a90e1da0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-32.webp new file mode 100644 index 0000000000..9a90a59008 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-48.webp new file mode 100644 index 0000000000..6fd6b5d1c7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-64.webp new file mode 100644 index 0000000000..0242bd95a8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AF-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-16.webp new file mode 100644 index 0000000000..826ad12f94 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-24.webp new file mode 100644 index 0000000000..5fb8939e55 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-32.webp new file mode 100644 index 0000000000..853ff799d1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-48.webp new file mode 100644 index 0000000000..a1d67ad78f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-64.webp new file mode 100644 index 0000000000..0c3f03583c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-16.webp new file mode 100644 index 0000000000..5aaa5ba17c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-24.webp new file mode 100644 index 0000000000..50da65810b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-32.webp new file mode 100644 index 0000000000..836a5517af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-48.webp new file mode 100644 index 0000000000..fff732310f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-64.webp new file mode 100644 index 0000000000..1e278549a7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-16.webp new file mode 100644 index 0000000000..1ed6fbcb91 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-24.webp new file mode 100644 index 0000000000..a7e7e6b67d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-32.webp new file mode 100644 index 0000000000..dbe5e53e8d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-48.webp new file mode 100644 index 0000000000..fccb66affb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-64.webp new file mode 100644 index 0000000000..a866774f9a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-16.webp new file mode 100644 index 0000000000..e99becdeaf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-24.webp new file mode 100644 index 0000000000..502ab24627 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-32.webp new file mode 100644 index 0000000000..b0cc26105c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-48.webp new file mode 100644 index 0000000000..f2b1066f4e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-64.webp new file mode 100644 index 0000000000..080e1b0adc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-16.webp new file mode 100644 index 0000000000..aaacbfea8f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-24.webp new file mode 100644 index 0000000000..31fafffcb8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-32.webp new file mode 100644 index 0000000000..dfa4cefd67 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-48.webp new file mode 100644 index 0000000000..edf1503b81 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-64.webp new file mode 100644 index 0000000000..354ac1121a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-16.webp new file mode 100644 index 0000000000..8f9e86fc56 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-24.webp new file mode 100644 index 0000000000..90c9c58620 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-32.webp new file mode 100644 index 0000000000..65089dffaf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-48.webp new file mode 100644 index 0000000000..7eebe0abbe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-64.webp new file mode 100644 index 0000000000..a580693e37 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AL-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-16.webp new file mode 100644 index 0000000000..40b7e25fd1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-24.webp new file mode 100644 index 0000000000..7f65a0fc3a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-32.webp new file mode 100644 index 0000000000..9245f54996 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-48.webp new file mode 100644 index 0000000000..4f6a7fd83e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-64.webp new file mode 100644 index 0000000000..d92feccc5e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-16.webp new file mode 100644 index 0000000000..9ed908438a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-24.webp new file mode 100644 index 0000000000..6c256e7d2a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-32.webp new file mode 100644 index 0000000000..a64ef024a4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-48.webp new file mode 100644 index 0000000000..9aa933f267 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-64.webp new file mode 100644 index 0000000000..6dcb4091e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-16.webp new file mode 100644 index 0000000000..d1751e2123 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-24.webp new file mode 100644 index 0000000000..9b00063d5a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-32.webp new file mode 100644 index 0000000000..dd2dc798e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-48.webp new file mode 100644 index 0000000000..c7304891ce Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-64.webp new file mode 100644 index 0000000000..3ad8dfc8fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-16.webp new file mode 100644 index 0000000000..497b0bf8ca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-24.webp new file mode 100644 index 0000000000..765e894371 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-32.webp new file mode 100644 index 0000000000..a5fd9ad070 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-48.webp new file mode 100644 index 0000000000..b3aa158e46 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-64.webp new file mode 100644 index 0000000000..d00cbeb675 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-16.webp new file mode 100644 index 0000000000..4eefd2af89 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-24.webp new file mode 100644 index 0000000000..00f740dbac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-32.webp new file mode 100644 index 0000000000..49992897d8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-48.webp new file mode 100644 index 0000000000..893a42d591 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-64.webp new file mode 100644 index 0000000000..cd49aafe3b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-16.webp new file mode 100644 index 0000000000..fe40fb06ef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-24.webp new file mode 100644 index 0000000000..fae9821569 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-32.webp new file mode 100644 index 0000000000..438944aa98 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-48.webp new file mode 100644 index 0000000000..ed063ce304 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-64.webp new file mode 100644 index 0000000000..22cb24da24 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-16.webp new file mode 100644 index 0000000000..f2a62abe93 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-24.webp new file mode 100644 index 0000000000..d81b024f40 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-32.webp new file mode 100644 index 0000000000..2b7bbb14ac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-48.webp new file mode 100644 index 0000000000..857b2feb8a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-64.webp new file mode 100644 index 0000000000..b0e5bda166 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-16.webp new file mode 100644 index 0000000000..4f030f508e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-24.webp new file mode 100644 index 0000000000..ed7adf2e99 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-32.webp new file mode 100644 index 0000000000..2c813f9913 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-48.webp new file mode 100644 index 0000000000..916c42a085 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-64.webp new file mode 100644 index 0000000000..91b57e1a59 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AQ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-16.webp new file mode 100644 index 0000000000..0a39e0a0fd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-24.webp new file mode 100644 index 0000000000..142e544db5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-32.webp new file mode 100644 index 0000000000..619dd07266 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-48.webp new file mode 100644 index 0000000000..82b09d30b8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-64.webp new file mode 100644 index 0000000000..fca783ae1a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-16.webp new file mode 100644 index 0000000000..fbfca67bdf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-24.webp new file mode 100644 index 0000000000..f15fc279b8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-32.webp new file mode 100644 index 0000000000..0b7dcb4f11 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-48.webp new file mode 100644 index 0000000000..8340045f5c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-64.webp new file mode 100644 index 0000000000..4238f852b9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-16.webp new file mode 100644 index 0000000000..d33370353a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-24.webp new file mode 100644 index 0000000000..cdf1283d38 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-32.webp new file mode 100644 index 0000000000..e02b426b05 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-48.webp new file mode 100644 index 0000000000..f499099b1f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-64.webp new file mode 100644 index 0000000000..cd81b80e1a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-16.webp new file mode 100644 index 0000000000..330f777a97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-24.webp new file mode 100644 index 0000000000..d4ff9bffb0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-32.webp new file mode 100644 index 0000000000..8c4562c93d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-48.webp new file mode 100644 index 0000000000..9e3b6541bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-64.webp new file mode 100644 index 0000000000..847eb47e47 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-16.webp new file mode 100644 index 0000000000..ba1b9ceab6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-24.webp new file mode 100644 index 0000000000..12a4f6d411 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-32.webp new file mode 100644 index 0000000000..af1ba99464 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-48.webp new file mode 100644 index 0000000000..0ba07f4583 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-64.webp new file mode 100644 index 0000000000..352fec1ae5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-16.webp new file mode 100644 index 0000000000..407d2d67a4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-24.webp new file mode 100644 index 0000000000..f7b207b995 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-32.webp new file mode 100644 index 0000000000..724712c818 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-48.webp new file mode 100644 index 0000000000..f07ee345fb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-64.webp new file mode 100644 index 0000000000..7706267321 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-16.webp new file mode 100644 index 0000000000..fc84a4538a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-24.webp new file mode 100644 index 0000000000..b4e2820591 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-32.webp new file mode 100644 index 0000000000..139f241225 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-48.webp new file mode 100644 index 0000000000..e857f24aca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-64.webp new file mode 100644 index 0000000000..4d0323adb2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-16.webp new file mode 100644 index 0000000000..c38f7afcb8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-24.webp new file mode 100644 index 0000000000..6912451a24 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-32.webp new file mode 100644 index 0000000000..1164ec8b76 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-48.webp new file mode 100644 index 0000000000..abd57905ec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-64.webp new file mode 100644 index 0000000000..1271ca7648 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-16.webp new file mode 100644 index 0000000000..1e6432d12f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-24.webp new file mode 100644 index 0000000000..205d079211 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-32.webp new file mode 100644 index 0000000000..dbd7e28292 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-48.webp new file mode 100644 index 0000000000..074b9d4235 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-64.webp new file mode 100644 index 0000000000..5c63b4b3b6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-16.webp new file mode 100644 index 0000000000..5c83b4f1ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-24.webp new file mode 100644 index 0000000000..d97ca42a78 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-32.webp new file mode 100644 index 0000000000..93cdbb190e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-48.webp new file mode 100644 index 0000000000..e9d1e71b6a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-64.webp new file mode 100644 index 0000000000..6c119ade9d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-16.webp new file mode 100644 index 0000000000..70d0bb5bb2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-24.webp new file mode 100644 index 0000000000..8fa15df092 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-32.webp new file mode 100644 index 0000000000..ba3eb7da01 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-48.webp new file mode 100644 index 0000000000..b358bf5029 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-64.webp new file mode 100644 index 0000000000..b8480640d0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-16.webp new file mode 100644 index 0000000000..a30276307b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-24.webp new file mode 100644 index 0000000000..3ac374cb6f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-32.webp new file mode 100644 index 0000000000..4c1bb396b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-48.webp new file mode 100644 index 0000000000..2450170964 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-64.webp new file mode 100644 index 0000000000..3df577e9e2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AX-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-16.webp new file mode 100644 index 0000000000..12e3440b97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-24.webp new file mode 100644 index 0000000000..8fa538d581 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-32.webp new file mode 100644 index 0000000000..c36fd6b057 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-48.webp new file mode 100644 index 0000000000..f245a7c986 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-64.webp new file mode 100644 index 0000000000..20d466f3a7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-16.webp new file mode 100644 index 0000000000..f77b531c12 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-24.webp new file mode 100644 index 0000000000..cfbb84569d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-32.webp new file mode 100644 index 0000000000..d8eb4dd780 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-48.webp new file mode 100644 index 0000000000..b248551c6b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-64.webp new file mode 100644 index 0000000000..de6c98968d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/AZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-16.webp new file mode 100644 index 0000000000..c62b639707 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-24.webp new file mode 100644 index 0000000000..da3cb6c890 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-32.webp new file mode 100644 index 0000000000..cedbd55440 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-48.webp new file mode 100644 index 0000000000..1f14c70f1d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-64.webp new file mode 100644 index 0000000000..9d11e60ed3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-16.webp new file mode 100644 index 0000000000..11cefce715 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-24.webp new file mode 100644 index 0000000000..4ac1f69db1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-32.webp new file mode 100644 index 0000000000..78ca7ee3cf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-48.webp new file mode 100644 index 0000000000..fdfbab65b8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-64.webp new file mode 100644 index 0000000000..7824db6d9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-16.webp new file mode 100644 index 0000000000..8c5d8c268d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-24.webp new file mode 100644 index 0000000000..748d13c6c0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-32.webp new file mode 100644 index 0000000000..7bb16b9756 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-48.webp new file mode 100644 index 0000000000..bd8a5615d4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-64.webp new file mode 100644 index 0000000000..5a4fe8db4a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-16.webp new file mode 100644 index 0000000000..14738786b3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-24.webp new file mode 100644 index 0000000000..a6c054834e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-32.webp new file mode 100644 index 0000000000..fe37b7ea05 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-48.webp new file mode 100644 index 0000000000..337408cffe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-64.webp new file mode 100644 index 0000000000..606a6810e6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BB-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-16.webp new file mode 100644 index 0000000000..8eb339dd9d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-24.webp new file mode 100644 index 0000000000..8fc7412ed8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-32.webp new file mode 100644 index 0000000000..9df012eddb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-48.webp new file mode 100644 index 0000000000..2706a4803d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-64.webp new file mode 100644 index 0000000000..62582a9e7d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-16.webp new file mode 100644 index 0000000000..0e5f16265f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-24.webp new file mode 100644 index 0000000000..2e1643f3dc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-32.webp new file mode 100644 index 0000000000..a90ca1adfc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-48.webp new file mode 100644 index 0000000000..1d70666446 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-64.webp new file mode 100644 index 0000000000..e48d301462 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BD-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-16.webp new file mode 100644 index 0000000000..675a8ee3e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-24.webp new file mode 100644 index 0000000000..c75a365e01 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-32.webp new file mode 100644 index 0000000000..522c3fe74d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-48.webp new file mode 100644 index 0000000000..5d732dc88a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-64.webp new file mode 100644 index 0000000000..c1ffd3e546 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-16.webp new file mode 100644 index 0000000000..1a4677cd22 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-24.webp new file mode 100644 index 0000000000..0254595e9d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-32.webp new file mode 100644 index 0000000000..88e7e3bcd1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-48.webp new file mode 100644 index 0000000000..32bbc3e409 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-64.webp new file mode 100644 index 0000000000..2cb5b94def Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-16.webp new file mode 100644 index 0000000000..ec78f64bc0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-24.webp new file mode 100644 index 0000000000..d93828c47a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-32.webp new file mode 100644 index 0000000000..a255cd3885 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-48.webp new file mode 100644 index 0000000000..05dfc6ef8e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-64.webp new file mode 100644 index 0000000000..98f70ded6a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-16.webp new file mode 100644 index 0000000000..d8fc838edd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-24.webp new file mode 100644 index 0000000000..69440a1126 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-32.webp new file mode 100644 index 0000000000..661d5b1e80 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-48.webp new file mode 100644 index 0000000000..abfc1b0175 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-64.webp new file mode 100644 index 0000000000..9bdc2265c4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BF-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-16.webp new file mode 100644 index 0000000000..949477f86b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-24.webp new file mode 100644 index 0000000000..92226732bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-32.webp new file mode 100644 index 0000000000..b8af36eae4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-48.webp new file mode 100644 index 0000000000..189b987b97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-64.webp new file mode 100644 index 0000000000..99e1572c4f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-16.webp new file mode 100644 index 0000000000..88691fa6eb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-24.webp new file mode 100644 index 0000000000..f3487180fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-32.webp new file mode 100644 index 0000000000..ab0aa6acc9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-48.webp new file mode 100644 index 0000000000..9024706ae7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-64.webp new file mode 100644 index 0000000000..67ad0fabd9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-16.webp new file mode 100644 index 0000000000..90ff070411 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-24.webp new file mode 100644 index 0000000000..d5fce8cd26 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-32.webp new file mode 100644 index 0000000000..30207a56ef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-48.webp new file mode 100644 index 0000000000..8ea3bf889c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-64.webp new file mode 100644 index 0000000000..a299f1ba81 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-16.webp new file mode 100644 index 0000000000..c80296d02b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-24.webp new file mode 100644 index 0000000000..f908896530 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-32.webp new file mode 100644 index 0000000000..5862746318 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-48.webp new file mode 100644 index 0000000000..6e451b6652 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-64.webp new file mode 100644 index 0000000000..05745debf8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-16.webp new file mode 100644 index 0000000000..93293b5587 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-24.webp new file mode 100644 index 0000000000..783caadeca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-32.webp new file mode 100644 index 0000000000..c81fbf19a2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-48.webp new file mode 100644 index 0000000000..a6b4f2492e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-64.webp new file mode 100644 index 0000000000..dc20de07c6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-16.webp new file mode 100644 index 0000000000..d75318d2a9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-24.webp new file mode 100644 index 0000000000..9921fe1468 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-32.webp new file mode 100644 index 0000000000..fd0f0d2f54 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-48.webp new file mode 100644 index 0000000000..eef4250b25 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-64.webp new file mode 100644 index 0000000000..afda115670 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-16.webp new file mode 100644 index 0000000000..21922df2eb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-24.webp new file mode 100644 index 0000000000..4223dbf193 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-32.webp new file mode 100644 index 0000000000..8f06f94bd6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-48.webp new file mode 100644 index 0000000000..72bdbaaee1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-64.webp new file mode 100644 index 0000000000..590d3d020d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-16.webp new file mode 100644 index 0000000000..b6ddc0e497 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-24.webp new file mode 100644 index 0000000000..201800d83e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-32.webp new file mode 100644 index 0000000000..1becf15e31 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-48.webp new file mode 100644 index 0000000000..0979fcf3f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-64.webp new file mode 100644 index 0000000000..ca512b6120 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BJ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-16.webp new file mode 100644 index 0000000000..f736c7a980 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-24.webp new file mode 100644 index 0000000000..d57a8d2ad2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-32.webp new file mode 100644 index 0000000000..ebb13ef693 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-48.webp new file mode 100644 index 0000000000..3e65531657 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-64.webp new file mode 100644 index 0000000000..b5add876d0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-16.webp new file mode 100644 index 0000000000..d984c1c498 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-24.webp new file mode 100644 index 0000000000..3fc1a1b00a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-32.webp new file mode 100644 index 0000000000..761586d426 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-48.webp new file mode 100644 index 0000000000..3402c0c62a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-64.webp new file mode 100644 index 0000000000..005d12d3cf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-16.webp new file mode 100644 index 0000000000..9029cf8346 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-24.webp new file mode 100644 index 0000000000..020be4c6c4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-32.webp new file mode 100644 index 0000000000..174c5f810f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-48.webp new file mode 100644 index 0000000000..03c9f8b018 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-64.webp new file mode 100644 index 0000000000..367795e034 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-16.webp new file mode 100644 index 0000000000..e491e05f7b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-24.webp new file mode 100644 index 0000000000..284acd1053 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-32.webp new file mode 100644 index 0000000000..471c8a5538 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-48.webp new file mode 100644 index 0000000000..6564a8b0e9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-64.webp new file mode 100644 index 0000000000..bfd00e657c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-16.webp new file mode 100644 index 0000000000..2ca92f3a6e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-24.webp new file mode 100644 index 0000000000..869f341a78 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-32.webp new file mode 100644 index 0000000000..3adcc4de93 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-48.webp new file mode 100644 index 0000000000..30455f744c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-64.webp new file mode 100644 index 0000000000..3d3b84c785 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-16.webp new file mode 100644 index 0000000000..f8340dc951 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-24.webp new file mode 100644 index 0000000000..38d826390f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-32.webp new file mode 100644 index 0000000000..788c0ff77d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-48.webp new file mode 100644 index 0000000000..1e66aa912b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-64.webp new file mode 100644 index 0000000000..3cfb9425bc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-16.webp new file mode 100644 index 0000000000..c49c4f14c0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-24.webp new file mode 100644 index 0000000000..8f629d443a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-32.webp new file mode 100644 index 0000000000..ce9f392f33 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-48.webp new file mode 100644 index 0000000000..c4f865d3d1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-64.webp new file mode 100644 index 0000000000..10131f2a28 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-16.webp new file mode 100644 index 0000000000..bccf6a9837 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-24.webp new file mode 100644 index 0000000000..b28044c8e3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-32.webp new file mode 100644 index 0000000000..fbba6ba0a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-48.webp new file mode 100644 index 0000000000..b7134afec5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-64.webp new file mode 100644 index 0000000000..dce64dbf44 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-16.webp new file mode 100644 index 0000000000..eeecb160a2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-24.webp new file mode 100644 index 0000000000..0085b6178a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-32.webp new file mode 100644 index 0000000000..0d7f7a0b4d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-48.webp new file mode 100644 index 0000000000..c1936a91f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-64.webp new file mode 100644 index 0000000000..bcf66612b0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-16.webp new file mode 100644 index 0000000000..dff68e7d7a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-24.webp new file mode 100644 index 0000000000..294b1de0ef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-32.webp new file mode 100644 index 0000000000..867d570aaa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-48.webp new file mode 100644 index 0000000000..27f88666d9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-64.webp new file mode 100644 index 0000000000..7a5dbbb15c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-16.webp new file mode 100644 index 0000000000..67d062d7e3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-24.webp new file mode 100644 index 0000000000..158cecc357 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-32.webp new file mode 100644 index 0000000000..67d186053a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-48.webp new file mode 100644 index 0000000000..b8a4966633 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-64.webp new file mode 100644 index 0000000000..eec722c8be Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-16.webp new file mode 100644 index 0000000000..da0636cff2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-24.webp new file mode 100644 index 0000000000..ce9688bd25 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-32.webp new file mode 100644 index 0000000000..538c8ac67c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-48.webp new file mode 100644 index 0000000000..57cecd5f50 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-64.webp new file mode 100644 index 0000000000..6020837964 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-16.webp new file mode 100644 index 0000000000..b51157317e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-24.webp new file mode 100644 index 0000000000..f6527b51b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-32.webp new file mode 100644 index 0000000000..7e47aad583 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-48.webp new file mode 100644 index 0000000000..92192c0865 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-64.webp new file mode 100644 index 0000000000..13d0f10cc3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-16.webp new file mode 100644 index 0000000000..53f3d3884c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-24.webp new file mode 100644 index 0000000000..3ab64d0e9c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-32.webp new file mode 100644 index 0000000000..d8455b95c5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-48.webp new file mode 100644 index 0000000000..0f9b3b7ebe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-64.webp new file mode 100644 index 0000000000..aa202807e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-16.webp new file mode 100644 index 0000000000..f7f1c19106 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-24.webp new file mode 100644 index 0000000000..b5f0bdf6e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-32.webp new file mode 100644 index 0000000000..ef9d091ac4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-48.webp new file mode 100644 index 0000000000..566b2c05e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-64.webp new file mode 100644 index 0000000000..167f15f6af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-16.webp new file mode 100644 index 0000000000..a7290d0ebf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-24.webp new file mode 100644 index 0000000000..7e354e0914 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-32.webp new file mode 100644 index 0000000000..0a90bae715 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-48.webp new file mode 100644 index 0000000000..fbf3907266 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-64.webp new file mode 100644 index 0000000000..2a6db00b9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-16.webp new file mode 100644 index 0000000000..0d0f370b29 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-24.webp new file mode 100644 index 0000000000..f42df86947 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-32.webp new file mode 100644 index 0000000000..51baae95d2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-48.webp new file mode 100644 index 0000000000..e579d8170c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-64.webp new file mode 100644 index 0000000000..e9a48be5f7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-16.webp new file mode 100644 index 0000000000..078c1d608c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-24.webp new file mode 100644 index 0000000000..61cda09683 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-32.webp new file mode 100644 index 0000000000..1187290838 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-48.webp new file mode 100644 index 0000000000..c02d7a59f7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-64.webp new file mode 100644 index 0000000000..31e9cf44a4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/BZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-16.webp new file mode 100644 index 0000000000..a40a95790f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-24.webp new file mode 100644 index 0000000000..0d9b388332 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-32.webp new file mode 100644 index 0000000000..c717990f33 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-48.webp new file mode 100644 index 0000000000..7fe81a3db1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-64.webp new file mode 100644 index 0000000000..4d320165b8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-16.webp new file mode 100644 index 0000000000..e7c95df962 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-24.webp new file mode 100644 index 0000000000..5d58080b9a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-32.webp new file mode 100644 index 0000000000..63895c6a1c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-48.webp new file mode 100644 index 0000000000..65ad033570 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-64.webp new file mode 100644 index 0000000000..20da66b722 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-16.webp new file mode 100644 index 0000000000..35dc139499 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-24.webp new file mode 100644 index 0000000000..81e9aa925d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-32.webp new file mode 100644 index 0000000000..c3827daaf4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-48.webp new file mode 100644 index 0000000000..1af6022efe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-64.webp new file mode 100644 index 0000000000..d39af8918e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-16.webp new file mode 100644 index 0000000000..56b408fbe4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-24.webp new file mode 100644 index 0000000000..ac3b33df77 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-32.webp new file mode 100644 index 0000000000..a695c7dd6b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-48.webp new file mode 100644 index 0000000000..aab58e89f5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-64.webp new file mode 100644 index 0000000000..5ce1e086ac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CC-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-16.webp new file mode 100644 index 0000000000..ed984b03a4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-24.webp new file mode 100644 index 0000000000..65fe24bf90 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-32.webp new file mode 100644 index 0000000000..3374ce6b7f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-48.webp new file mode 100644 index 0000000000..d520ef7e57 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-64.webp new file mode 100644 index 0000000000..bcb72f2133 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-16.webp new file mode 100644 index 0000000000..c910ad2e3a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-24.webp new file mode 100644 index 0000000000..4bcc7beb4b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-32.webp new file mode 100644 index 0000000000..be93d766fa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-48.webp new file mode 100644 index 0000000000..1ce9f85814 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-64.webp new file mode 100644 index 0000000000..22c16ac019 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CD-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-16.webp new file mode 100644 index 0000000000..1e964254bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-24.webp new file mode 100644 index 0000000000..d16e140dca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-32.webp new file mode 100644 index 0000000000..f7a2d44106 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-48.webp new file mode 100644 index 0000000000..2c15e51915 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-64.webp new file mode 100644 index 0000000000..5fd5b9d14c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-16.webp new file mode 100644 index 0000000000..6ed17d99f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-24.webp new file mode 100644 index 0000000000..9160b0bf78 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-32.webp new file mode 100644 index 0000000000..b62168f5e0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-48.webp new file mode 100644 index 0000000000..c6c203ae6b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-64.webp new file mode 100644 index 0000000000..1511523c84 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CF-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-16.webp new file mode 100644 index 0000000000..3b2ac6e143 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-24.webp new file mode 100644 index 0000000000..72018fceb6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-32.webp new file mode 100644 index 0000000000..44f1eefdb8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-48.webp new file mode 100644 index 0000000000..9077f6276d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-64.webp new file mode 100644 index 0000000000..244a95777a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-16.webp new file mode 100644 index 0000000000..2c295dee95 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-24.webp new file mode 100644 index 0000000000..1ee3adcd58 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-32.webp new file mode 100644 index 0000000000..187c5c9d18 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-48.webp new file mode 100644 index 0000000000..da419218ad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-64.webp new file mode 100644 index 0000000000..a7f2c13848 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-16.webp new file mode 100644 index 0000000000..386e07e092 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-24.webp new file mode 100644 index 0000000000..7ce0c19ae0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-32.webp new file mode 100644 index 0000000000..c29ce63688 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-48.webp new file mode 100644 index 0000000000..17a6214992 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-64.webp new file mode 100644 index 0000000000..01afa525d5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-16.webp new file mode 100644 index 0000000000..9e72b489e6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-24.webp new file mode 100644 index 0000000000..ac142ae3f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-32.webp new file mode 100644 index 0000000000..6f8d9e895a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-48.webp new file mode 100644 index 0000000000..c5b8fe98bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-64.webp new file mode 100644 index 0000000000..213d2e8e4b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-16.webp new file mode 100644 index 0000000000..d20e03002a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-24.webp new file mode 100644 index 0000000000..d2a24c1b02 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-32.webp new file mode 100644 index 0000000000..1383d69b66 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-48.webp new file mode 100644 index 0000000000..61d0284176 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-64.webp new file mode 100644 index 0000000000..b023cc3265 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-16.webp new file mode 100644 index 0000000000..171b69fda0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-24.webp new file mode 100644 index 0000000000..590c221579 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-32.webp new file mode 100644 index 0000000000..b1d3665d90 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-48.webp new file mode 100644 index 0000000000..9b1b15ea97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-64.webp new file mode 100644 index 0000000000..552ca17334 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-16.webp new file mode 100644 index 0000000000..9cfce140a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-24.webp new file mode 100644 index 0000000000..ef86eb1b33 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-32.webp new file mode 100644 index 0000000000..12f59e4b92 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-48.webp new file mode 100644 index 0000000000..a90d52c744 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-64.webp new file mode 100644 index 0000000000..7b505ce121 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-16.webp new file mode 100644 index 0000000000..ed2919910f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-24.webp new file mode 100644 index 0000000000..7e0d4e2221 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-32.webp new file mode 100644 index 0000000000..daab02fc6d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-48.webp new file mode 100644 index 0000000000..adbd09aa51 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-64.webp new file mode 100644 index 0000000000..051aa170f7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-16.webp new file mode 100644 index 0000000000..df6e992708 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-24.webp new file mode 100644 index 0000000000..083630fd70 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-32.webp new file mode 100644 index 0000000000..a9e290d27d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-48.webp new file mode 100644 index 0000000000..ae3320893f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-64.webp new file mode 100644 index 0000000000..7f353c460d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-16.webp new file mode 100644 index 0000000000..0155c15807 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-24.webp new file mode 100644 index 0000000000..1be61e86d6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-32.webp new file mode 100644 index 0000000000..622608e44d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-48.webp new file mode 100644 index 0000000000..692a4251a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-64.webp new file mode 100644 index 0000000000..1c960e024f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CL-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-16.webp new file mode 100644 index 0000000000..7a5a8b29d0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-24.webp new file mode 100644 index 0000000000..256b7c4456 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-32.webp new file mode 100644 index 0000000000..4ade5b8eac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-48.webp new file mode 100644 index 0000000000..abf79d1e8c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-64.webp new file mode 100644 index 0000000000..b8b7909bb9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-16.webp new file mode 100644 index 0000000000..06b3834a6b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-24.webp new file mode 100644 index 0000000000..7ebd509611 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-32.webp new file mode 100644 index 0000000000..e179c85f03 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-48.webp new file mode 100644 index 0000000000..4545679b67 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-64.webp new file mode 100644 index 0000000000..1844321571 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-16.webp new file mode 100644 index 0000000000..a9be72fadd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-24.webp new file mode 100644 index 0000000000..ca4608af35 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-32.webp new file mode 100644 index 0000000000..c2a3a71372 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-48.webp new file mode 100644 index 0000000000..d298bc8658 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-64.webp new file mode 100644 index 0000000000..2b094535bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-16.webp new file mode 100644 index 0000000000..18da2f8474 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-24.webp new file mode 100644 index 0000000000..2a2b94b61f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-32.webp new file mode 100644 index 0000000000..6c9e1751ac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-48.webp new file mode 100644 index 0000000000..c1e8c4a99a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-64.webp new file mode 100644 index 0000000000..e42660aad1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-16.webp new file mode 100644 index 0000000000..cab3f90984 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-24.webp new file mode 100644 index 0000000000..93fc230fde Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-32.webp new file mode 100644 index 0000000000..a2c5fbe3d3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-48.webp new file mode 100644 index 0000000000..7d395efeec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-64.webp new file mode 100644 index 0000000000..7edb6181bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-16.webp new file mode 100644 index 0000000000..2f3910b100 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-24.webp new file mode 100644 index 0000000000..e53642c6c7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-32.webp new file mode 100644 index 0000000000..d29ad7d3f8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-48.webp new file mode 100644 index 0000000000..8097c8eebf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-64.webp new file mode 100644 index 0000000000..f34160ea54 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-16.webp new file mode 100644 index 0000000000..a172363ac6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-24.webp new file mode 100644 index 0000000000..add7579173 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-32.webp new file mode 100644 index 0000000000..aadc29b20b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-48.webp new file mode 100644 index 0000000000..6738821dd4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-64.webp new file mode 100644 index 0000000000..a9f03d6b24 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-16.webp new file mode 100644 index 0000000000..9a02124ea0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-24.webp new file mode 100644 index 0000000000..86eb5feefc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-32.webp new file mode 100644 index 0000000000..994f10aab8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-48.webp new file mode 100644 index 0000000000..3318bf958c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-64.webp new file mode 100644 index 0000000000..31fc3d4c68 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-16.webp new file mode 100644 index 0000000000..b48010f360 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-24.webp new file mode 100644 index 0000000000..c211689bb9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-32.webp new file mode 100644 index 0000000000..62dc80cf38 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-48.webp new file mode 100644 index 0000000000..12cf2ba03d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-64.webp new file mode 100644 index 0000000000..59624f3179 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-16.webp new file mode 100644 index 0000000000..d4255218ef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-24.webp new file mode 100644 index 0000000000..1cb97443a9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-32.webp new file mode 100644 index 0000000000..657e369859 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-48.webp new file mode 100644 index 0000000000..2a7b99ac45 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-64.webp new file mode 100644 index 0000000000..9b9c78388f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-16.webp new file mode 100644 index 0000000000..0dd76fc24d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-24.webp new file mode 100644 index 0000000000..da4f7d11fc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-32.webp new file mode 100644 index 0000000000..1465615b46 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-48.webp new file mode 100644 index 0000000000..c7d535e2ef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-64.webp new file mode 100644 index 0000000000..b070ef9754 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-16.webp new file mode 100644 index 0000000000..bc47c19107 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-24.webp new file mode 100644 index 0000000000..671ee5f1f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-32.webp new file mode 100644 index 0000000000..3f39f936f7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-48.webp new file mode 100644 index 0000000000..9cd4619673 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-64.webp new file mode 100644 index 0000000000..805dc02f0f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CV-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-16.webp new file mode 100644 index 0000000000..5a2919a531 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-24.webp new file mode 100644 index 0000000000..83e8b49d38 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-32.webp new file mode 100644 index 0000000000..11a53c5221 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-48.webp new file mode 100644 index 0000000000..712ad4ad9f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-64.webp new file mode 100644 index 0000000000..7fcabf36fb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-16.webp new file mode 100644 index 0000000000..f3402ed8e9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-24.webp new file mode 100644 index 0000000000..f850424e32 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-32.webp new file mode 100644 index 0000000000..1f58d9e694 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-48.webp new file mode 100644 index 0000000000..96782b2931 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-64.webp new file mode 100644 index 0000000000..10ac61a4aa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-16.webp new file mode 100644 index 0000000000..079b23a28b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-24.webp new file mode 100644 index 0000000000..210d7c5c25 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-32.webp new file mode 100644 index 0000000000..cde62b6505 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-48.webp new file mode 100644 index 0000000000..15a7a1d587 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-64.webp new file mode 100644 index 0000000000..33841f45bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-16.webp new file mode 100644 index 0000000000..a0bc868e27 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-24.webp new file mode 100644 index 0000000000..bd27ba19a2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-32.webp new file mode 100644 index 0000000000..c3dab69565 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-48.webp new file mode 100644 index 0000000000..1eb9f75e19 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-64.webp new file mode 100644 index 0000000000..5832135348 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CX-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-16.webp new file mode 100644 index 0000000000..bbfba0621a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-24.webp new file mode 100644 index 0000000000..cbfc93bb12 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-32.webp new file mode 100644 index 0000000000..f9b0bf8696 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-48.webp new file mode 100644 index 0000000000..5351608e76 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-64.webp new file mode 100644 index 0000000000..5d1175ad96 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-16.webp new file mode 100644 index 0000000000..e08cb12365 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-24.webp new file mode 100644 index 0000000000..5a45d30fb9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-32.webp new file mode 100644 index 0000000000..15bdbe23fc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-48.webp new file mode 100644 index 0000000000..179fe2038e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-64.webp new file mode 100644 index 0000000000..3499bdf54d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-16.webp new file mode 100644 index 0000000000..26f918a00b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-24.webp new file mode 100644 index 0000000000..dc94de9ea8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-32.webp new file mode 100644 index 0000000000..82f8720818 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-48.webp new file mode 100644 index 0000000000..d5e8659998 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-64.webp new file mode 100644 index 0000000000..38a0d665fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-16.webp new file mode 100644 index 0000000000..a6bd5d6875 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-24.webp new file mode 100644 index 0000000000..9c852d403c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-32.webp new file mode 100644 index 0000000000..6f11177f5d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-48.webp new file mode 100644 index 0000000000..eaa8c6387f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-64.webp new file mode 100644 index 0000000000..2640151832 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/CZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-16.webp new file mode 100644 index 0000000000..599e44952f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-24.webp new file mode 100644 index 0000000000..72bde772bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-32.webp new file mode 100644 index 0000000000..80dee51d0e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-48.webp new file mode 100644 index 0000000000..9d0f610032 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-64.webp new file mode 100644 index 0000000000..f64e2e3c72 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-16.webp new file mode 100644 index 0000000000..a6a49481c3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-24.webp new file mode 100644 index 0000000000..2d1fcb9e78 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-32.webp new file mode 100644 index 0000000000..604415bd76 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-48.webp new file mode 100644 index 0000000000..8ec87ec431 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-64.webp new file mode 100644 index 0000000000..5783c104b4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-16.webp new file mode 100644 index 0000000000..fdc00dcd72 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-24.webp new file mode 100644 index 0000000000..1fcab77bf6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-32.webp new file mode 100644 index 0000000000..1bd59820ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-48.webp new file mode 100644 index 0000000000..08934c878c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-64.webp new file mode 100644 index 0000000000..faff3d3a71 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-16.webp new file mode 100644 index 0000000000..fb52a1d0e2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-24.webp new file mode 100644 index 0000000000..217ad0e28a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-32.webp new file mode 100644 index 0000000000..7000407edd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-48.webp new file mode 100644 index 0000000000..c092d9ead0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-64.webp new file mode 100644 index 0000000000..cd83a63a91 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DJ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-16.webp new file mode 100644 index 0000000000..e928e07ea1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-24.webp new file mode 100644 index 0000000000..1b70a3a1cf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-32.webp new file mode 100644 index 0000000000..403bd3b508 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-48.webp new file mode 100644 index 0000000000..8ab3783cbf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-64.webp new file mode 100644 index 0000000000..74493f7221 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-16.webp new file mode 100644 index 0000000000..09204aef26 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-24.webp new file mode 100644 index 0000000000..c0a32604cc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-32.webp new file mode 100644 index 0000000000..34647ddf5a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-48.webp new file mode 100644 index 0000000000..244482c6b3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-64.webp new file mode 100644 index 0000000000..005607277d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-16.webp new file mode 100644 index 0000000000..f29ffd6064 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-24.webp new file mode 100644 index 0000000000..659884d988 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-32.webp new file mode 100644 index 0000000000..9413965ba8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-48.webp new file mode 100644 index 0000000000..9a524f8dda Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-64.webp new file mode 100644 index 0000000000..6fa0d9f845 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-16.webp new file mode 100644 index 0000000000..73022f95d6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-24.webp new file mode 100644 index 0000000000..f10a2a8ea2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-32.webp new file mode 100644 index 0000000000..bc768935a0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-48.webp new file mode 100644 index 0000000000..608f151f01 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-64.webp new file mode 100644 index 0000000000..9124fd3b50 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-16.webp new file mode 100644 index 0000000000..3151d1ae5d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-24.webp new file mode 100644 index 0000000000..9e97d062fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-32.webp new file mode 100644 index 0000000000..c9eace4bca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-48.webp new file mode 100644 index 0000000000..915c5ab9d0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-64.webp new file mode 100644 index 0000000000..ad386c918a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-16.webp new file mode 100644 index 0000000000..f603779d81 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-24.webp new file mode 100644 index 0000000000..a9c5e80b5f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-32.webp new file mode 100644 index 0000000000..09d07a9b90 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-48.webp new file mode 100644 index 0000000000..242639a347 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-64.webp new file mode 100644 index 0000000000..0e9449eca1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-16.webp new file mode 100644 index 0000000000..4763940519 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-24.webp new file mode 100644 index 0000000000..5192c1d3af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-32.webp new file mode 100644 index 0000000000..91ab34d713 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-48.webp new file mode 100644 index 0000000000..9be9fde154 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-64.webp new file mode 100644 index 0000000000..8d3e88eda7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-16.webp new file mode 100644 index 0000000000..5c0983b3b7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-24.webp new file mode 100644 index 0000000000..78a35458c5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-32.webp new file mode 100644 index 0000000000..5bc15a5b31 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-48.webp new file mode 100644 index 0000000000..5e3f5835a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-64.webp new file mode 100644 index 0000000000..c54bd54b5c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/DZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-16.webp new file mode 100644 index 0000000000..c355cb0ae9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-24.webp new file mode 100644 index 0000000000..431f32e780 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-32.webp new file mode 100644 index 0000000000..5baa40f953 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-48.webp new file mode 100644 index 0000000000..abc5753f06 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-64.webp new file mode 100644 index 0000000000..21e8f8652a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-16.webp new file mode 100644 index 0000000000..f7c96e2a2a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-24.webp new file mode 100644 index 0000000000..3a06334b79 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-32.webp new file mode 100644 index 0000000000..b1d95c3d1e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-48.webp new file mode 100644 index 0000000000..139c0da8f6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-64.webp new file mode 100644 index 0000000000..59739b60e8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EC-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-16.webp new file mode 100644 index 0000000000..fe8ea79d23 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-24.webp new file mode 100644 index 0000000000..ee505cedf2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-32.webp new file mode 100644 index 0000000000..a9a3c95fef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-48.webp new file mode 100644 index 0000000000..325ce07669 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-64.webp new file mode 100644 index 0000000000..c196d28429 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-16.webp new file mode 100644 index 0000000000..ac258c5648 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-24.webp new file mode 100644 index 0000000000..da7158f441 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-32.webp new file mode 100644 index 0000000000..00a70b24e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-48.webp new file mode 100644 index 0000000000..72b8f84cfd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-64.webp new file mode 100644 index 0000000000..df18447aae Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-16.webp new file mode 100644 index 0000000000..a7e079f25e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-24.webp new file mode 100644 index 0000000000..86866a9c7f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-32.webp new file mode 100644 index 0000000000..793407348c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-48.webp new file mode 100644 index 0000000000..dc13e65c55 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-64.webp new file mode 100644 index 0000000000..6daa92bbf3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-16.webp new file mode 100644 index 0000000000..bea8760f9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-24.webp new file mode 100644 index 0000000000..f6c47f770d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-32.webp new file mode 100644 index 0000000000..ce9483273a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-48.webp new file mode 100644 index 0000000000..30a34fe0e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-64.webp new file mode 100644 index 0000000000..1dcd1d5271 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-16.webp new file mode 100644 index 0000000000..f876503dea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-24.webp new file mode 100644 index 0000000000..552276d0d2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-32.webp new file mode 100644 index 0000000000..a75fda58e5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-48.webp new file mode 100644 index 0000000000..4f5fe01c4a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-64.webp new file mode 100644 index 0000000000..80dcaf738d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-16.webp new file mode 100644 index 0000000000..e4370960e3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-24.webp new file mode 100644 index 0000000000..b52afd447c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-32.webp new file mode 100644 index 0000000000..5a996e929b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-48.webp new file mode 100644 index 0000000000..64474761fa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-64.webp new file mode 100644 index 0000000000..054aa93627 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/EH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-16.webp new file mode 100644 index 0000000000..cde8f22670 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-24.webp new file mode 100644 index 0000000000..f4c71a9840 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-32.webp new file mode 100644 index 0000000000..8039b82f76 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-48.webp new file mode 100644 index 0000000000..79fb76b5c1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-64.webp new file mode 100644 index 0000000000..7b4ff840e3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-16.webp new file mode 100644 index 0000000000..0dcf57830e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-24.webp new file mode 100644 index 0000000000..dab9a90f57 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-32.webp new file mode 100644 index 0000000000..6e0917eaea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-48.webp new file mode 100644 index 0000000000..d2fcfb7c9d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-64.webp new file mode 100644 index 0000000000..f09bdae3e2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ER-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-16.webp new file mode 100644 index 0000000000..5078befae9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-24.webp new file mode 100644 index 0000000000..880ac2efb7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-32.webp new file mode 100644 index 0000000000..348b09a11e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-48.webp new file mode 100644 index 0000000000..701ce0e05d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-64.webp new file mode 100644 index 0000000000..6ea9aaf609 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-16.webp new file mode 100644 index 0000000000..6c85b22e2c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-24.webp new file mode 100644 index 0000000000..cb20dc9ab1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-32.webp new file mode 100644 index 0000000000..0da9332f4d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-48.webp new file mode 100644 index 0000000000..746af1f6b1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-64.webp new file mode 100644 index 0000000000..2b8decbc9f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ES-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-16.webp new file mode 100644 index 0000000000..7361325160 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-24.webp new file mode 100644 index 0000000000..60802dda0c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-32.webp new file mode 100644 index 0000000000..e30b86a362 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-48.webp new file mode 100644 index 0000000000..02b3af4ef4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-64.webp new file mode 100644 index 0000000000..dbf5ac0927 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-16.webp new file mode 100644 index 0000000000..0bd86f0be4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-24.webp new file mode 100644 index 0000000000..fe5dcf0c3d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-32.webp new file mode 100644 index 0000000000..d90962b2ab Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-48.webp new file mode 100644 index 0000000000..bbdbf76564 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-64.webp new file mode 100644 index 0000000000..7db1146acc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ET-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-16.webp new file mode 100644 index 0000000000..1089a4795f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-24.webp new file mode 100644 index 0000000000..293df680f3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-32.webp new file mode 100644 index 0000000000..266c3401ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-48.webp new file mode 100644 index 0000000000..dd177a4936 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-64.webp new file mode 100644 index 0000000000..15052cb764 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-16.webp new file mode 100644 index 0000000000..5dafcd8a97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-24.webp new file mode 100644 index 0000000000..6243c67655 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-32.webp new file mode 100644 index 0000000000..10546b9ad6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-48.webp new file mode 100644 index 0000000000..eb59d91375 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-64.webp new file mode 100644 index 0000000000..4bb511c5ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-16.webp new file mode 100644 index 0000000000..d427b41445 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-24.webp new file mode 100644 index 0000000000..db9c3f2f0b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-32.webp new file mode 100644 index 0000000000..beb89594f2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-48.webp new file mode 100644 index 0000000000..1a36dcb945 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-64.webp new file mode 100644 index 0000000000..e7eab8c886 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-16.webp new file mode 100644 index 0000000000..414d866591 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-24.webp new file mode 100644 index 0000000000..8a8ed5fc1b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-32.webp new file mode 100644 index 0000000000..60fae432ee Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-48.webp new file mode 100644 index 0000000000..a068d33dc0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-64.webp new file mode 100644 index 0000000000..640592f2ba Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FJ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-16.webp new file mode 100644 index 0000000000..c0aeb46482 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-24.webp new file mode 100644 index 0000000000..9b4a31b286 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-32.webp new file mode 100644 index 0000000000..b56af734ae Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-48.webp new file mode 100644 index 0000000000..4c17c26236 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-64.webp new file mode 100644 index 0000000000..da9f1af0dd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-16.webp new file mode 100644 index 0000000000..62288e5a74 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-24.webp new file mode 100644 index 0000000000..a115949133 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-32.webp new file mode 100644 index 0000000000..b15cb54c50 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-48.webp new file mode 100644 index 0000000000..79f31b3413 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-64.webp new file mode 100644 index 0000000000..2c072014f5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-16.webp new file mode 100644 index 0000000000..7cb8dfa9f8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-24.webp new file mode 100644 index 0000000000..c794c56a00 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-32.webp new file mode 100644 index 0000000000..3e01445de4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-48.webp new file mode 100644 index 0000000000..e4b9aed1d4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-64.webp new file mode 100644 index 0000000000..f4591f5620 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-16.webp new file mode 100644 index 0000000000..c8ab6c6be3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-24.webp new file mode 100644 index 0000000000..12c77d81c0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-32.webp new file mode 100644 index 0000000000..f8fcfaa315 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-48.webp new file mode 100644 index 0000000000..e3965bcc5d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-64.webp new file mode 100644 index 0000000000..0d05b36be0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-16.webp new file mode 100644 index 0000000000..856d751e14 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-24.webp new file mode 100644 index 0000000000..c1461f4a7d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-32.webp new file mode 100644 index 0000000000..75839ac08d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-48.webp new file mode 100644 index 0000000000..abb16e7ceb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-64.webp new file mode 100644 index 0000000000..4b7ad101dc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-16.webp new file mode 100644 index 0000000000..36fb0b6f98 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-24.webp new file mode 100644 index 0000000000..1fa19d4baa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-32.webp new file mode 100644 index 0000000000..d9d5605c0f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-48.webp new file mode 100644 index 0000000000..41cd0191a9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-64.webp new file mode 100644 index 0000000000..fd647ab98c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-16.webp new file mode 100644 index 0000000000..d1577b3a64 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-24.webp new file mode 100644 index 0000000000..5ea851c1ba Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-32.webp new file mode 100644 index 0000000000..9e6ed6fb56 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-48.webp new file mode 100644 index 0000000000..131122103a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-64.webp new file mode 100644 index 0000000000..470154095d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-16.webp new file mode 100644 index 0000000000..a25646a31a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-24.webp new file mode 100644 index 0000000000..d295fd5f24 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-32.webp new file mode 100644 index 0000000000..51689d091b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-48.webp new file mode 100644 index 0000000000..0d1d071677 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-64.webp new file mode 100644 index 0000000000..b5056bd8bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/FR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-16.webp new file mode 100644 index 0000000000..04ee83c0c7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-24.webp new file mode 100644 index 0000000000..185a05eb35 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-32.webp new file mode 100644 index 0000000000..938e112a90 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-48.webp new file mode 100644 index 0000000000..a8ee184ebd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-64.webp new file mode 100644 index 0000000000..0ad3b385bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-16.webp new file mode 100644 index 0000000000..dcd70e79e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-24.webp new file mode 100644 index 0000000000..2e97315444 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-32.webp new file mode 100644 index 0000000000..4b585f01da Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-48.webp new file mode 100644 index 0000000000..6f2c229131 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-64.webp new file mode 100644 index 0000000000..292d335878 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-16.webp new file mode 100644 index 0000000000..7f9582c698 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-24.webp new file mode 100644 index 0000000000..06037b192c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-32.webp new file mode 100644 index 0000000000..bb1d17a9be Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-48.webp new file mode 100644 index 0000000000..40dcce3cc1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-64.webp new file mode 100644 index 0000000000..da760c0802 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-16.webp new file mode 100644 index 0000000000..477a9c4514 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-24.webp new file mode 100644 index 0000000000..50be9294bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-32.webp new file mode 100644 index 0000000000..7f346d304c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-48.webp new file mode 100644 index 0000000000..efd358ccb8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-64.webp new file mode 100644 index 0000000000..977b7923c0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GB-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-16.webp new file mode 100644 index 0000000000..899d7ab56d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-24.webp new file mode 100644 index 0000000000..a2614b20c4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-32.webp new file mode 100644 index 0000000000..10ce4b84f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-48.webp new file mode 100644 index 0000000000..ebfce561e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-64.webp new file mode 100644 index 0000000000..fec624b4bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-16.webp new file mode 100644 index 0000000000..a9f3baddbb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-24.webp new file mode 100644 index 0000000000..58c36cc3b1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-32.webp new file mode 100644 index 0000000000..7d7c57d30a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-48.webp new file mode 100644 index 0000000000..cb3ca1fc51 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-64.webp new file mode 100644 index 0000000000..4965e2e85c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GD-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-16.webp new file mode 100644 index 0000000000..623ad49016 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-24.webp new file mode 100644 index 0000000000..cf92acf349 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-32.webp new file mode 100644 index 0000000000..cafaafc401 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-48.webp new file mode 100644 index 0000000000..db0b586c6a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-64.webp new file mode 100644 index 0000000000..00285ce4ec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-16.webp new file mode 100644 index 0000000000..94e7e6e84f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-24.webp new file mode 100644 index 0000000000..8749fbf3f3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-32.webp new file mode 100644 index 0000000000..12523d4de2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-48.webp new file mode 100644 index 0000000000..ea5dd94c55 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-64.webp new file mode 100644 index 0000000000..5b8928a8bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-16.webp new file mode 100644 index 0000000000..b5692c101c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-24.webp new file mode 100644 index 0000000000..b30c8140aa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-32.webp new file mode 100644 index 0000000000..dd71d4a717 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-48.webp new file mode 100644 index 0000000000..c6be652b58 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-64.webp new file mode 100644 index 0000000000..3eeee889d3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-16.webp new file mode 100644 index 0000000000..aee6f6f451 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-24.webp new file mode 100644 index 0000000000..cf2c456730 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-32.webp new file mode 100644 index 0000000000..7c41a48800 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-48.webp new file mode 100644 index 0000000000..87c357a0a0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-64.webp new file mode 100644 index 0000000000..4ff94e21b9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-16.webp new file mode 100644 index 0000000000..3c34da914b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-24.webp new file mode 100644 index 0000000000..1931b56cac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-32.webp new file mode 100644 index 0000000000..e3c97691a9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-48.webp new file mode 100644 index 0000000000..1c7756b603 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-64.webp new file mode 100644 index 0000000000..1a4fc795a7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-16.webp new file mode 100644 index 0000000000..f44244608c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-24.webp new file mode 100644 index 0000000000..fd844114a8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-32.webp new file mode 100644 index 0000000000..df48eee43c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-48.webp new file mode 100644 index 0000000000..96486fec08 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-64.webp new file mode 100644 index 0000000000..5d129c9c25 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-16.webp new file mode 100644 index 0000000000..7cf79f2dfb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-24.webp new file mode 100644 index 0000000000..771daed945 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-32.webp new file mode 100644 index 0000000000..2651d07f6b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-48.webp new file mode 100644 index 0000000000..83c7b8199a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-64.webp new file mode 100644 index 0000000000..6dc5b9f994 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-16.webp new file mode 100644 index 0000000000..2961650825 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-24.webp new file mode 100644 index 0000000000..5f4d10c546 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-32.webp new file mode 100644 index 0000000000..89af6ed2d5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-48.webp new file mode 100644 index 0000000000..3a5cf6b897 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-64.webp new file mode 100644 index 0000000000..3f66ad3791 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-16.webp new file mode 100644 index 0000000000..a7f7461c8b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-24.webp new file mode 100644 index 0000000000..bd118f9558 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-32.webp new file mode 100644 index 0000000000..fad79dc9de Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-48.webp new file mode 100644 index 0000000000..1a75922323 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-64.webp new file mode 100644 index 0000000000..f00a546485 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-16.webp new file mode 100644 index 0000000000..7f2bbd212c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-24.webp new file mode 100644 index 0000000000..e60808573d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-32.webp new file mode 100644 index 0000000000..3551f472ca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-48.webp new file mode 100644 index 0000000000..4249a04a4d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-64.webp new file mode 100644 index 0000000000..a921435aee Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GL-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-16.webp new file mode 100644 index 0000000000..32f5cb66e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-24.webp new file mode 100644 index 0000000000..6915e3279b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-32.webp new file mode 100644 index 0000000000..1e3e1b9cb2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-48.webp new file mode 100644 index 0000000000..d62f4dd045 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-64.webp new file mode 100644 index 0000000000..88d9e0a669 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-16.webp new file mode 100644 index 0000000000..797bd158d3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-24.webp new file mode 100644 index 0000000000..72dab27453 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-32.webp new file mode 100644 index 0000000000..0c6e691e5f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-48.webp new file mode 100644 index 0000000000..d39a7d9240 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-64.webp new file mode 100644 index 0000000000..f51e44877d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-16.webp new file mode 100644 index 0000000000..3c98f71f05 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-24.webp new file mode 100644 index 0000000000..7b6089c837 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-32.webp new file mode 100644 index 0000000000..8b19a7b8d6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-48.webp new file mode 100644 index 0000000000..92c63be12b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-64.webp new file mode 100644 index 0000000000..ba06c14a74 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-16.webp new file mode 100644 index 0000000000..513696be60 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-24.webp new file mode 100644 index 0000000000..cf1e84d604 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-32.webp new file mode 100644 index 0000000000..c74ad1faf7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-48.webp new file mode 100644 index 0000000000..bacba91785 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-64.webp new file mode 100644 index 0000000000..a6e793fb22 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-16.webp new file mode 100644 index 0000000000..179b415fc0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-24.webp new file mode 100644 index 0000000000..034a2d6d40 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-32.webp new file mode 100644 index 0000000000..634761bc20 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-48.webp new file mode 100644 index 0000000000..6d4380a488 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-64.webp new file mode 100644 index 0000000000..a63cab1a97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-16.webp new file mode 100644 index 0000000000..a67c4fb453 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-24.webp new file mode 100644 index 0000000000..47a51d7b26 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-32.webp new file mode 100644 index 0000000000..abafcb2fa0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-48.webp new file mode 100644 index 0000000000..8ccebe033b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-64.webp new file mode 100644 index 0000000000..c05f5244f8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GQ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-16.webp new file mode 100644 index 0000000000..37338dfe9d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-24.webp new file mode 100644 index 0000000000..2b9e592f6b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-32.webp new file mode 100644 index 0000000000..f47050b2a0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-48.webp new file mode 100644 index 0000000000..21072ce9ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-64.webp new file mode 100644 index 0000000000..31a3b0a631 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-16.webp new file mode 100644 index 0000000000..0c1439e636 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-24.webp new file mode 100644 index 0000000000..fd57739540 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-32.webp new file mode 100644 index 0000000000..dfbe72c470 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-48.webp new file mode 100644 index 0000000000..2e13d77ed8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-64.webp new file mode 100644 index 0000000000..90def7f35d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-16.webp new file mode 100644 index 0000000000..60b918858d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-24.webp new file mode 100644 index 0000000000..4ef448c667 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-32.webp new file mode 100644 index 0000000000..695a304ad4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-48.webp new file mode 100644 index 0000000000..f99a1f1477 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-64.webp new file mode 100644 index 0000000000..e43ad98919 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-16.webp new file mode 100644 index 0000000000..4e4d5b38ad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-24.webp new file mode 100644 index 0000000000..b27ff977c5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-32.webp new file mode 100644 index 0000000000..9b7aad8d69 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-48.webp new file mode 100644 index 0000000000..0c0f99d380 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-64.webp new file mode 100644 index 0000000000..e90bf7baf7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-16.webp new file mode 100644 index 0000000000..3207f9f86d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-24.webp new file mode 100644 index 0000000000..931a1fc2a1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-32.webp new file mode 100644 index 0000000000..4521f77e95 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-48.webp new file mode 100644 index 0000000000..990ae79b47 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-64.webp new file mode 100644 index 0000000000..47b4351317 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-16.webp new file mode 100644 index 0000000000..cd3f45067f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-24.webp new file mode 100644 index 0000000000..f0b3078ea2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-32.webp new file mode 100644 index 0000000000..365df6ea1b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-48.webp new file mode 100644 index 0000000000..53c8627fea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-64.webp new file mode 100644 index 0000000000..ed57aae9a8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-16.webp new file mode 100644 index 0000000000..a8318bcdfc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-24.webp new file mode 100644 index 0000000000..2884be2ecd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-32.webp new file mode 100644 index 0000000000..aa4006119c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-48.webp new file mode 100644 index 0000000000..acc1ca253a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-64.webp new file mode 100644 index 0000000000..a738ff1549 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-16.webp new file mode 100644 index 0000000000..eccd896bda Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-24.webp new file mode 100644 index 0000000000..a829b9717f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-32.webp new file mode 100644 index 0000000000..356e9ae551 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-48.webp new file mode 100644 index 0000000000..9dbff2eed2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-64.webp new file mode 100644 index 0000000000..f15ed0a49d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-16.webp new file mode 100644 index 0000000000..bac9b5f23c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-24.webp new file mode 100644 index 0000000000..ab0006f1ef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-32.webp new file mode 100644 index 0000000000..386c04c693 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-48.webp new file mode 100644 index 0000000000..2326edc8d1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-64.webp new file mode 100644 index 0000000000..00da29e80f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-16.webp new file mode 100644 index 0000000000..1f666d92b3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-24.webp new file mode 100644 index 0000000000..3a6cac3e74 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-32.webp new file mode 100644 index 0000000000..e789d6d420 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-48.webp new file mode 100644 index 0000000000..8c8358cb30 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-64.webp new file mode 100644 index 0000000000..4f7734e245 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-16.webp new file mode 100644 index 0000000000..9590c6d8fd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-24.webp new file mode 100644 index 0000000000..7ec78db932 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-32.webp new file mode 100644 index 0000000000..5342dbe2cc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-48.webp new file mode 100644 index 0000000000..236ed041db Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-64.webp new file mode 100644 index 0000000000..6690150733 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-16.webp new file mode 100644 index 0000000000..d18b30ec7d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-24.webp new file mode 100644 index 0000000000..d528c6c94b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-32.webp new file mode 100644 index 0000000000..83f0e55725 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-48.webp new file mode 100644 index 0000000000..52d37f634c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-64.webp new file mode 100644 index 0000000000..5a801c0a20 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/GY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-16.webp new file mode 100644 index 0000000000..ddbae5ad5d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-24.webp new file mode 100644 index 0000000000..8642a5c66d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-32.webp new file mode 100644 index 0000000000..b1ac7ace93 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-48.webp new file mode 100644 index 0000000000..d703ff9759 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-64.webp new file mode 100644 index 0000000000..95ac002a95 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-16.webp new file mode 100644 index 0000000000..2496866f30 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-24.webp new file mode 100644 index 0000000000..d3e4c167bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-32.webp new file mode 100644 index 0000000000..f5481153a1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-48.webp new file mode 100644 index 0000000000..12b0d8fd79 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-64.webp new file mode 100644 index 0000000000..87384169f9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-16.webp new file mode 100644 index 0000000000..979a664552 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-24.webp new file mode 100644 index 0000000000..3b37710070 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-32.webp new file mode 100644 index 0000000000..ea851ce343 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-48.webp new file mode 100644 index 0000000000..c9b96be0ba Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-64.webp new file mode 100644 index 0000000000..739da4adca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-16.webp new file mode 100644 index 0000000000..f0b9e5f893 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-24.webp new file mode 100644 index 0000000000..0834febec1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-32.webp new file mode 100644 index 0000000000..19152aae94 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-48.webp new file mode 100644 index 0000000000..1c6b29ec96 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-64.webp new file mode 100644 index 0000000000..2ea652442e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-16.webp new file mode 100644 index 0000000000..b69b66bc27 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-24.webp new file mode 100644 index 0000000000..b9298cb40b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-32.webp new file mode 100644 index 0000000000..50a104d567 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-48.webp new file mode 100644 index 0000000000..79ad16afed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-64.webp new file mode 100644 index 0000000000..15b7986fbf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-16.webp new file mode 100644 index 0000000000..601bece895 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-24.webp new file mode 100644 index 0000000000..a134a386ba Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-32.webp new file mode 100644 index 0000000000..2ba3764718 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-48.webp new file mode 100644 index 0000000000..0e2b28d828 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-64.webp new file mode 100644 index 0000000000..ed6e7be523 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-16.webp new file mode 100644 index 0000000000..4862a102f8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-24.webp new file mode 100644 index 0000000000..384bba5959 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-32.webp new file mode 100644 index 0000000000..0bdcbd78bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-48.webp new file mode 100644 index 0000000000..46d4b8ef3d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-64.webp new file mode 100644 index 0000000000..3e215404e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-16.webp new file mode 100644 index 0000000000..766f1e425a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-24.webp new file mode 100644 index 0000000000..cfb290375f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-32.webp new file mode 100644 index 0000000000..bb2b8f60be Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-48.webp new file mode 100644 index 0000000000..fd6d9af338 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-64.webp new file mode 100644 index 0000000000..5047f9b105 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-16.webp new file mode 100644 index 0000000000..69cc44fb29 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-24.webp new file mode 100644 index 0000000000..7de4b61bf9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-32.webp new file mode 100644 index 0000000000..8cb0c15c00 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-48.webp new file mode 100644 index 0000000000..9514f0e4ec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-64.webp new file mode 100644 index 0000000000..93b4c5a524 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-16.webp new file mode 100644 index 0000000000..bc80843630 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-24.webp new file mode 100644 index 0000000000..74abec5465 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-32.webp new file mode 100644 index 0000000000..1e19db9357 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-48.webp new file mode 100644 index 0000000000..379d016f8d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-64.webp new file mode 100644 index 0000000000..e5c35cdbdf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/HU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-16.webp new file mode 100644 index 0000000000..865a09a31c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-24.webp new file mode 100644 index 0000000000..fe2a3f35f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-32.webp new file mode 100644 index 0000000000..0f07fa078e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-48.webp new file mode 100644 index 0000000000..dc6a5ddc09 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-64.webp new file mode 100644 index 0000000000..4cea63b78b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-16.webp new file mode 100644 index 0000000000..7ed9cee478 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-24.webp new file mode 100644 index 0000000000..9d06178c38 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-32.webp new file mode 100644 index 0000000000..27ceb7f350 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-48.webp new file mode 100644 index 0000000000..0fddc50392 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-64.webp new file mode 100644 index 0000000000..ea16189d5b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ID-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-16.webp new file mode 100644 index 0000000000..b769efef9b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-24.webp new file mode 100644 index 0000000000..a24b582093 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-32.webp new file mode 100644 index 0000000000..e10aec095e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-48.webp new file mode 100644 index 0000000000..52ab8aeb22 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-64.webp new file mode 100644 index 0000000000..729ecf6eba Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-16.webp new file mode 100644 index 0000000000..3fc8bbb0d7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-24.webp new file mode 100644 index 0000000000..fc5b6a3142 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-32.webp new file mode 100644 index 0000000000..9cf7731c21 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-48.webp new file mode 100644 index 0000000000..07c1b890e7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-64.webp new file mode 100644 index 0000000000..0754a98620 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-16.webp new file mode 100644 index 0000000000..cf50c77bc9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-24.webp new file mode 100644 index 0000000000..f955fd7658 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-32.webp new file mode 100644 index 0000000000..9bfa8b8e92 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-48.webp new file mode 100644 index 0000000000..92ea9a503f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-64.webp new file mode 100644 index 0000000000..bd80c65bb1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-16.webp new file mode 100644 index 0000000000..7b637043d3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-24.webp new file mode 100644 index 0000000000..dc9e0f8388 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-32.webp new file mode 100644 index 0000000000..c972473fe2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-48.webp new file mode 100644 index 0000000000..f978d7149e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-64.webp new file mode 100644 index 0000000000..ee62e29b6e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IL-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-16.webp new file mode 100644 index 0000000000..afe77dea29 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-24.webp new file mode 100644 index 0000000000..521447299c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-32.webp new file mode 100644 index 0000000000..4ce4519609 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-48.webp new file mode 100644 index 0000000000..76999ff9e2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-64.webp new file mode 100644 index 0000000000..ac60b10011 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-16.webp new file mode 100644 index 0000000000..cc05a4b4c2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-24.webp new file mode 100644 index 0000000000..f04b551e9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-32.webp new file mode 100644 index 0000000000..0ad7e8952c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-48.webp new file mode 100644 index 0000000000..913d960f60 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-64.webp new file mode 100644 index 0000000000..71b2f7981d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-16.webp new file mode 100644 index 0000000000..61272fab32 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-24.webp new file mode 100644 index 0000000000..e1fb47dd89 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-32.webp new file mode 100644 index 0000000000..49bc46222c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-48.webp new file mode 100644 index 0000000000..81d2695f84 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-64.webp new file mode 100644 index 0000000000..cdf6f00e01 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-16.webp new file mode 100644 index 0000000000..8d731cb49c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-24.webp new file mode 100644 index 0000000000..0972947ccb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-32.webp new file mode 100644 index 0000000000..2923b5e7fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-48.webp new file mode 100644 index 0000000000..36f75e5133 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-64.webp new file mode 100644 index 0000000000..a768c406c2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-16.webp new file mode 100644 index 0000000000..cae8326a36 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-24.webp new file mode 100644 index 0000000000..fe7366568f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-32.webp new file mode 100644 index 0000000000..a94027409a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-48.webp new file mode 100644 index 0000000000..130c4cd30f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-64.webp new file mode 100644 index 0000000000..ac20e98ea4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-16.webp new file mode 100644 index 0000000000..756d4bc29b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-24.webp new file mode 100644 index 0000000000..1a26ec3648 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-32.webp new file mode 100644 index 0000000000..3dfc61ae3d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-48.webp new file mode 100644 index 0000000000..283f28522b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-64.webp new file mode 100644 index 0000000000..e6fbf78a30 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IQ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-16.webp new file mode 100644 index 0000000000..dee73c1d09 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-24.webp new file mode 100644 index 0000000000..6ae524bda9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-32.webp new file mode 100644 index 0000000000..61d160e58f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-48.webp new file mode 100644 index 0000000000..3c00b22130 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-64.webp new file mode 100644 index 0000000000..4574fa0807 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-16.webp new file mode 100644 index 0000000000..fcaad4da26 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-24.webp new file mode 100644 index 0000000000..56981ee9a4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-32.webp new file mode 100644 index 0000000000..2100540ff2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-48.webp new file mode 100644 index 0000000000..0bb099acc5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-64.webp new file mode 100644 index 0000000000..dbe4eeeb3f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-16.webp new file mode 100644 index 0000000000..bbd3f37c96 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-24.webp new file mode 100644 index 0000000000..1799451da6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-32.webp new file mode 100644 index 0000000000..3529448aa9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-48.webp new file mode 100644 index 0000000000..eaf38ba431 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-64.webp new file mode 100644 index 0000000000..3b1f421721 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-16.webp new file mode 100644 index 0000000000..98a2c4b871 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-24.webp new file mode 100644 index 0000000000..6ff39ca06b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-32.webp new file mode 100644 index 0000000000..df09ef4688 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-48.webp new file mode 100644 index 0000000000..c0bf2ab7bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-64.webp new file mode 100644 index 0000000000..b1b9b53052 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-16.webp new file mode 100644 index 0000000000..1d276a424c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-24.webp new file mode 100644 index 0000000000..1d7579edf4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-32.webp new file mode 100644 index 0000000000..0b3ca4412c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-48.webp new file mode 100644 index 0000000000..8524868c5b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-64.webp new file mode 100644 index 0000000000..413aa6decd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-16.webp new file mode 100644 index 0000000000..4e4935c68e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-24.webp new file mode 100644 index 0000000000..baabf5f87b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-32.webp new file mode 100644 index 0000000000..df8f936306 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-48.webp new file mode 100644 index 0000000000..1e25949393 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-64.webp new file mode 100644 index 0000000000..1168f937b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/IT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-16.webp new file mode 100644 index 0000000000..7c1af24f6e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-24.webp new file mode 100644 index 0000000000..ae56797d11 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-32.webp new file mode 100644 index 0000000000..86b3e50434 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-48.webp new file mode 100644 index 0000000000..f79bc85cca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-64.webp new file mode 100644 index 0000000000..866047d0d4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-16.webp new file mode 100644 index 0000000000..2ca8c681d7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-24.webp new file mode 100644 index 0000000000..550852f926 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-32.webp new file mode 100644 index 0000000000..5954dbaa4e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-48.webp new file mode 100644 index 0000000000..702038eb16 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-64.webp new file mode 100644 index 0000000000..a851fca5bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-16.webp new file mode 100644 index 0000000000..f86d6f6610 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-24.webp new file mode 100644 index 0000000000..069fec0620 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-32.webp new file mode 100644 index 0000000000..3827dfe2d6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-48.webp new file mode 100644 index 0000000000..7bf4cdb693 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-64.webp new file mode 100644 index 0000000000..28e0e54993 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-16.webp new file mode 100644 index 0000000000..6ae504f217 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-24.webp new file mode 100644 index 0000000000..4bde0713fa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-32.webp new file mode 100644 index 0000000000..05fc110601 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-48.webp new file mode 100644 index 0000000000..928beeccd0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-64.webp new file mode 100644 index 0000000000..8367cd2290 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-16.webp new file mode 100644 index 0000000000..e56cbaa1e7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-24.webp new file mode 100644 index 0000000000..cc5ac88df2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-32.webp new file mode 100644 index 0000000000..79aa3287ee Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-48.webp new file mode 100644 index 0000000000..f1f8ea9e76 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-64.webp new file mode 100644 index 0000000000..b90e827ebc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-16.webp new file mode 100644 index 0000000000..4f2539ffe3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-24.webp new file mode 100644 index 0000000000..3b48a1169a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-32.webp new file mode 100644 index 0000000000..91ecfefba1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-48.webp new file mode 100644 index 0000000000..7ea984b332 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-64.webp new file mode 100644 index 0000000000..4c4b660ef1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-16.webp new file mode 100644 index 0000000000..2bde566433 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-24.webp new file mode 100644 index 0000000000..000bba590c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-32.webp new file mode 100644 index 0000000000..30348d0db3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-48.webp new file mode 100644 index 0000000000..b00a86fe08 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-64.webp new file mode 100644 index 0000000000..58fafeb903 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-16.webp new file mode 100644 index 0000000000..b6120ccf5d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-24.webp new file mode 100644 index 0000000000..e165a07def Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-32.webp new file mode 100644 index 0000000000..937fcaf4a2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-48.webp new file mode 100644 index 0000000000..208da51a08 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-64.webp new file mode 100644 index 0000000000..7b0acd2905 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/JP-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-16.webp new file mode 100644 index 0000000000..7da5c6004a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-24.webp new file mode 100644 index 0000000000..41349223ab Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-32.webp new file mode 100644 index 0000000000..d5e1ead509 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-48.webp new file mode 100644 index 0000000000..b5dab16acc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-64.webp new file mode 100644 index 0000000000..f1840766c2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-16.webp new file mode 100644 index 0000000000..6e6c97f96d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-24.webp new file mode 100644 index 0000000000..0d6215f9fb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-32.webp new file mode 100644 index 0000000000..686ab127ac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-48.webp new file mode 100644 index 0000000000..732d0714da Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-64.webp new file mode 100644 index 0000000000..1b8f6f9422 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-16.webp new file mode 100644 index 0000000000..3e3cf8736d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-24.webp new file mode 100644 index 0000000000..bb2f6ca414 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-32.webp new file mode 100644 index 0000000000..d9e47cafba Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-48.webp new file mode 100644 index 0000000000..8606c040f6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-64.webp new file mode 100644 index 0000000000..daf18337f2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-16.webp new file mode 100644 index 0000000000..50f3c8dbfd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-24.webp new file mode 100644 index 0000000000..644ac9bbf0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-32.webp new file mode 100644 index 0000000000..d8fc43c6b0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-48.webp new file mode 100644 index 0000000000..abe1d5c02b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-64.webp new file mode 100644 index 0000000000..0861390dbc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-16.webp new file mode 100644 index 0000000000..6defd3ab47 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-24.webp new file mode 100644 index 0000000000..0727e0ffac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-32.webp new file mode 100644 index 0000000000..e2feddc1c1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-48.webp new file mode 100644 index 0000000000..95e4ad3161 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-64.webp new file mode 100644 index 0000000000..cd5c336cc2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-16.webp new file mode 100644 index 0000000000..a950742f06 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-24.webp new file mode 100644 index 0000000000..66dc790f84 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-32.webp new file mode 100644 index 0000000000..0bbe71ed2e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-48.webp new file mode 100644 index 0000000000..8d0c6b7daa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-64.webp new file mode 100644 index 0000000000..95a78a7d06 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-16.webp new file mode 100644 index 0000000000..1f2a4d2ac8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-24.webp new file mode 100644 index 0000000000..ebef40fcf8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-32.webp new file mode 100644 index 0000000000..4af3734358 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-48.webp new file mode 100644 index 0000000000..d3bfabb927 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-64.webp new file mode 100644 index 0000000000..8160bcfd2b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-16.webp new file mode 100644 index 0000000000..1535b393cf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-24.webp new file mode 100644 index 0000000000..a5848b8091 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-32.webp new file mode 100644 index 0000000000..b11483304d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-48.webp new file mode 100644 index 0000000000..7cc65b6dad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-64.webp new file mode 100644 index 0000000000..685cc5ca57 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-16.webp new file mode 100644 index 0000000000..4869cdb6ea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-24.webp new file mode 100644 index 0000000000..f917774854 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-32.webp new file mode 100644 index 0000000000..d0777c30a7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-48.webp new file mode 100644 index 0000000000..8f9eba4043 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-64.webp new file mode 100644 index 0000000000..37c2465c16 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-16.webp new file mode 100644 index 0000000000..276b094447 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-24.webp new file mode 100644 index 0000000000..be2d99247d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-32.webp new file mode 100644 index 0000000000..a45d6d3e30 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-48.webp new file mode 100644 index 0000000000..66cb9fc25c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-64.webp new file mode 100644 index 0000000000..df458aef17 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-16.webp new file mode 100644 index 0000000000..c083fb0cb0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-24.webp new file mode 100644 index 0000000000..9e6cbbf173 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-32.webp new file mode 100644 index 0000000000..a8e65c2e3c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-48.webp new file mode 100644 index 0000000000..7a787d5b37 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-64.webp new file mode 100644 index 0000000000..078a70d794 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-16.webp new file mode 100644 index 0000000000..2b16083a04 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-24.webp new file mode 100644 index 0000000000..d49584dd2e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-32.webp new file mode 100644 index 0000000000..251bbe9ab4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-48.webp new file mode 100644 index 0000000000..b08eff5bbe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-64.webp new file mode 100644 index 0000000000..64f419a5b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-16.webp new file mode 100644 index 0000000000..d01689e059 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-24.webp new file mode 100644 index 0000000000..aa36b034b6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-32.webp new file mode 100644 index 0000000000..5ea2b7a731 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-48.webp new file mode 100644 index 0000000000..404e628975 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-64.webp new file mode 100644 index 0000000000..e6ec49ea4c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-16.webp new file mode 100644 index 0000000000..f66d1546be Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-24.webp new file mode 100644 index 0000000000..58a969e95a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-32.webp new file mode 100644 index 0000000000..65ab61a902 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-48.webp new file mode 100644 index 0000000000..1318c75de4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-64.webp new file mode 100644 index 0000000000..a5f00b1a96 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KP-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-16.webp new file mode 100644 index 0000000000..54aa3ec54b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-24.webp new file mode 100644 index 0000000000..6f6c63ef41 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-32.webp new file mode 100644 index 0000000000..9450ed0171 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-48.webp new file mode 100644 index 0000000000..f41cb5a9bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-64.webp new file mode 100644 index 0000000000..8ce9914c29 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-16.webp new file mode 100644 index 0000000000..4131ec19d8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-24.webp new file mode 100644 index 0000000000..f2d61540a3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-32.webp new file mode 100644 index 0000000000..63ba8f9d41 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-48.webp new file mode 100644 index 0000000000..4983814a25 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-64.webp new file mode 100644 index 0000000000..ab4c2866bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-16.webp new file mode 100644 index 0000000000..b73eaad48a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-24.webp new file mode 100644 index 0000000000..ec8f9ff558 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-32.webp new file mode 100644 index 0000000000..f28fef043a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-48.webp new file mode 100644 index 0000000000..59ba4fd9bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-64.webp new file mode 100644 index 0000000000..467b259738 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-16.webp new file mode 100644 index 0000000000..b52c08f2eb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-24.webp new file mode 100644 index 0000000000..c15a7fd394 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-32.webp new file mode 100644 index 0000000000..5f27bae944 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-48.webp new file mode 100644 index 0000000000..5a9714a8a7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-64.webp new file mode 100644 index 0000000000..3f87181b9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-16.webp new file mode 100644 index 0000000000..fee581940f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-24.webp new file mode 100644 index 0000000000..599f653ec0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-32.webp new file mode 100644 index 0000000000..7cffe9229b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-48.webp new file mode 100644 index 0000000000..a18bfec20f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-64.webp new file mode 100644 index 0000000000..9d54d5af86 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-16.webp new file mode 100644 index 0000000000..a9d1b46b3f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-24.webp new file mode 100644 index 0000000000..80afb47c63 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-32.webp new file mode 100644 index 0000000000..3730499c37 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-48.webp new file mode 100644 index 0000000000..6e5a4c2358 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-64.webp new file mode 100644 index 0000000000..3879e22d71 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-16.webp new file mode 100644 index 0000000000..66b70fb532 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-24.webp new file mode 100644 index 0000000000..9c5b146a1f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-32.webp new file mode 100644 index 0000000000..f2eed69897 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-48.webp new file mode 100644 index 0000000000..781f01bc14 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-64.webp new file mode 100644 index 0000000000..2b1857b0a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-16.webp new file mode 100644 index 0000000000..c6b1fdea11 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-24.webp new file mode 100644 index 0000000000..b3ff9d4765 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-32.webp new file mode 100644 index 0000000000..30afd7feb0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-48.webp new file mode 100644 index 0000000000..72187dba97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-64.webp new file mode 100644 index 0000000000..1c5f6c9f35 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/KZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-16.webp new file mode 100644 index 0000000000..b37510b7d1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-24.webp new file mode 100644 index 0000000000..4049a6ca81 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-32.webp new file mode 100644 index 0000000000..07f5f21e79 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-48.webp new file mode 100644 index 0000000000..ae737b5be6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-64.webp new file mode 100644 index 0000000000..e9bfdd0a43 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-16.webp new file mode 100644 index 0000000000..37ec71bdfa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-24.webp new file mode 100644 index 0000000000..d76b175e83 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-32.webp new file mode 100644 index 0000000000..bdc356fbac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-48.webp new file mode 100644 index 0000000000..b6a2cde9cf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-64.webp new file mode 100644 index 0000000000..bba689200b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-16.webp new file mode 100644 index 0000000000..14f03b831e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-24.webp new file mode 100644 index 0000000000..15a359615c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-32.webp new file mode 100644 index 0000000000..6acb10ffa2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-48.webp new file mode 100644 index 0000000000..50c839b412 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-64.webp new file mode 100644 index 0000000000..5458958c73 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-16.webp new file mode 100644 index 0000000000..e20de7d369 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-24.webp new file mode 100644 index 0000000000..45c774a946 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-32.webp new file mode 100644 index 0000000000..30d8a2962d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-48.webp new file mode 100644 index 0000000000..7edd9d2a4c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-64.webp new file mode 100644 index 0000000000..f7b96126be Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LB-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-16.webp new file mode 100644 index 0000000000..15a504300b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-24.webp new file mode 100644 index 0000000000..19fa9312f6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-32.webp new file mode 100644 index 0000000000..474637c94c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-48.webp new file mode 100644 index 0000000000..6326941718 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-64.webp new file mode 100644 index 0000000000..d3172e531d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-16.webp new file mode 100644 index 0000000000..0bbf2aeb37 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-24.webp new file mode 100644 index 0000000000..408bc68a65 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-32.webp new file mode 100644 index 0000000000..e1512d6e86 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-48.webp new file mode 100644 index 0000000000..ac7c891e0a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-64.webp new file mode 100644 index 0000000000..b9241d89b1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LC-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-16.webp new file mode 100644 index 0000000000..94689b8301 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-24.webp new file mode 100644 index 0000000000..cc3fd46f11 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-32.webp new file mode 100644 index 0000000000..202c572a96 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-48.webp new file mode 100644 index 0000000000..57ef48cb58 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-64.webp new file mode 100644 index 0000000000..5b16cc3485 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-16.webp new file mode 100644 index 0000000000..c6c36294d2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-24.webp new file mode 100644 index 0000000000..46fe0fa2d3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-32.webp new file mode 100644 index 0000000000..b45f5bec8d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-48.webp new file mode 100644 index 0000000000..3b83be1444 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-64.webp new file mode 100644 index 0000000000..fb764afa94 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-16.webp new file mode 100644 index 0000000000..e42725b8d3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-24.webp new file mode 100644 index 0000000000..f5f938fecf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-32.webp new file mode 100644 index 0000000000..dc1fbb672e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-48.webp new file mode 100644 index 0000000000..f15b79fc5c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-64.webp new file mode 100644 index 0000000000..a90b0353eb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-16.webp new file mode 100644 index 0000000000..2017a0e2bf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-24.webp new file mode 100644 index 0000000000..21ee81ee7c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-32.webp new file mode 100644 index 0000000000..6647dd9cca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-48.webp new file mode 100644 index 0000000000..22e8df45bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-64.webp new file mode 100644 index 0000000000..820296a09f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-16.webp new file mode 100644 index 0000000000..8d0a6f502c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-24.webp new file mode 100644 index 0000000000..ff9e8bfe2c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-32.webp new file mode 100644 index 0000000000..4184a2ed6d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-48.webp new file mode 100644 index 0000000000..3b68dc6ff7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-64.webp new file mode 100644 index 0000000000..96b9c0d6c9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-16.webp new file mode 100644 index 0000000000..c3647cf6d9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-24.webp new file mode 100644 index 0000000000..fdec4d9c98 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-32.webp new file mode 100644 index 0000000000..9b4c82f28d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-48.webp new file mode 100644 index 0000000000..bcc0597f4c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-64.webp new file mode 100644 index 0000000000..7eeb17c5f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-16.webp new file mode 100644 index 0000000000..ee43dad30b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-24.webp new file mode 100644 index 0000000000..f852231400 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-32.webp new file mode 100644 index 0000000000..c7797035c2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-48.webp new file mode 100644 index 0000000000..c1a10a41c6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-64.webp new file mode 100644 index 0000000000..d748085680 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-16.webp new file mode 100644 index 0000000000..7dc4e68c59 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-24.webp new file mode 100644 index 0000000000..2e2390f4ae Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-32.webp new file mode 100644 index 0000000000..7e6cce3291 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-48.webp new file mode 100644 index 0000000000..9fa3e22be1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-64.webp new file mode 100644 index 0000000000..3a8de5929e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-16.webp new file mode 100644 index 0000000000..6d37e1d8e6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-24.webp new file mode 100644 index 0000000000..415592f729 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-32.webp new file mode 100644 index 0000000000..6622385f17 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-48.webp new file mode 100644 index 0000000000..50e0402b21 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-64.webp new file mode 100644 index 0000000000..37bc3fa0dc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-16.webp new file mode 100644 index 0000000000..cae21fc026 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-24.webp new file mode 100644 index 0000000000..43eeb3a2d5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-32.webp new file mode 100644 index 0000000000..f15dbe6aa7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-48.webp new file mode 100644 index 0000000000..63f3184735 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-64.webp new file mode 100644 index 0000000000..55fb5280a1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-16.webp new file mode 100644 index 0000000000..31a46dc2c9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-24.webp new file mode 100644 index 0000000000..33c67fcf95 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-32.webp new file mode 100644 index 0000000000..0c7b76073e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-48.webp new file mode 100644 index 0000000000..11b6bff84c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-64.webp new file mode 100644 index 0000000000..0c7f886cb8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-16.webp new file mode 100644 index 0000000000..fea2a97948 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-24.webp new file mode 100644 index 0000000000..8dbb13b68a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-32.webp new file mode 100644 index 0000000000..5630dbecbb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-48.webp new file mode 100644 index 0000000000..5bb0fab038 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-64.webp new file mode 100644 index 0000000000..8e9d656098 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-16.webp new file mode 100644 index 0000000000..1e7a4d6041 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-24.webp new file mode 100644 index 0000000000..b2fe7bec07 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-32.webp new file mode 100644 index 0000000000..e732cdcd24 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-48.webp new file mode 100644 index 0000000000..9d87a7c8db Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-64.webp new file mode 100644 index 0000000000..865875688e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-16.webp new file mode 100644 index 0000000000..a970048435 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-24.webp new file mode 100644 index 0000000000..3ade253104 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-32.webp new file mode 100644 index 0000000000..3aa2db101a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-48.webp new file mode 100644 index 0000000000..21804ef203 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-64.webp new file mode 100644 index 0000000000..b15156d904 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LV-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-16.webp new file mode 100644 index 0000000000..e3e654be8f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-24.webp new file mode 100644 index 0000000000..55aef7bc00 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-32.webp new file mode 100644 index 0000000000..1f658dc81a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-48.webp new file mode 100644 index 0000000000..0640d0262b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-64.webp new file mode 100644 index 0000000000..5c8fbe53e3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-16.webp new file mode 100644 index 0000000000..3c4e779914 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-24.webp new file mode 100644 index 0000000000..b47b1a995b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-32.webp new file mode 100644 index 0000000000..da4faaecee Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-48.webp new file mode 100644 index 0000000000..aa89a4d1f0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-64.webp new file mode 100644 index 0000000000..1bf2608fbd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/LY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-16.webp new file mode 100644 index 0000000000..f4d86c7ff4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-24.webp new file mode 100644 index 0000000000..4e1728da6c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-32.webp new file mode 100644 index 0000000000..0f26bc4649 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-48.webp new file mode 100644 index 0000000000..bcdfb97558 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-64.webp new file mode 100644 index 0000000000..8492d7b627 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-16.webp new file mode 100644 index 0000000000..f1d3a979b3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-24.webp new file mode 100644 index 0000000000..0bbac100a4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-32.webp new file mode 100644 index 0000000000..0ceaa9309e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-48.webp new file mode 100644 index 0000000000..93cfc0a8a3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-64.webp new file mode 100644 index 0000000000..5191b0cf48 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-16.webp new file mode 100644 index 0000000000..865a09a31c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-24.webp new file mode 100644 index 0000000000..fe2a3f35f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-32.webp new file mode 100644 index 0000000000..0f07fa078e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-48.webp new file mode 100644 index 0000000000..dc6a5ddc09 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-64.webp new file mode 100644 index 0000000000..4cea63b78b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-16.webp new file mode 100644 index 0000000000..7ed9cee478 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-24.webp new file mode 100644 index 0000000000..9d06178c38 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-32.webp new file mode 100644 index 0000000000..27ceb7f350 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-48.webp new file mode 100644 index 0000000000..0fddc50392 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-64.webp new file mode 100644 index 0000000000..ea16189d5b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MC-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-16.webp new file mode 100644 index 0000000000..f7289da9d0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-24.webp new file mode 100644 index 0000000000..fc8414db51 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-32.webp new file mode 100644 index 0000000000..cb7569fe4d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-48.webp new file mode 100644 index 0000000000..829f252f33 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-64.webp new file mode 100644 index 0000000000..6e33cd6099 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-16.webp new file mode 100644 index 0000000000..d3bbcab22e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-24.webp new file mode 100644 index 0000000000..97be24d3e8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-32.webp new file mode 100644 index 0000000000..453d485c3c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-48.webp new file mode 100644 index 0000000000..c1c76c15ab Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-64.webp new file mode 100644 index 0000000000..69362a65e8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MD-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-16.webp new file mode 100644 index 0000000000..61522a6426 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-24.webp new file mode 100644 index 0000000000..0cfd20940b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-32.webp new file mode 100644 index 0000000000..3698b8b7e3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-48.webp new file mode 100644 index 0000000000..923590df36 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-64.webp new file mode 100644 index 0000000000..c7a8f12928 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-16.webp new file mode 100644 index 0000000000..c8d1268a11 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-24.webp new file mode 100644 index 0000000000..f535151d27 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-32.webp new file mode 100644 index 0000000000..adb0e68c47 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-48.webp new file mode 100644 index 0000000000..22a59ef771 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-64.webp new file mode 100644 index 0000000000..0926af2a37 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ME-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-16.webp new file mode 100644 index 0000000000..d67f1a22c1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-24.webp new file mode 100644 index 0000000000..2276edf0af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-32.webp new file mode 100644 index 0000000000..aff50275d0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-48.webp new file mode 100644 index 0000000000..e8ab9d3eda Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-64.webp new file mode 100644 index 0000000000..c94ce83d0d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-16.webp new file mode 100644 index 0000000000..fa53e1da8d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-24.webp new file mode 100644 index 0000000000..e9a7e1d09b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-32.webp new file mode 100644 index 0000000000..912d3f4e64 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-48.webp new file mode 100644 index 0000000000..2da5696aae Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-64.webp new file mode 100644 index 0000000000..7fff46c791 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MF-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-16.webp new file mode 100644 index 0000000000..ca44a43e49 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-24.webp new file mode 100644 index 0000000000..4d55252d44 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-32.webp new file mode 100644 index 0000000000..6b2920de85 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-48.webp new file mode 100644 index 0000000000..d46dc12e30 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-64.webp new file mode 100644 index 0000000000..84b4852cf6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-16.webp new file mode 100644 index 0000000000..a52da51892 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-24.webp new file mode 100644 index 0000000000..539c00abb3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-32.webp new file mode 100644 index 0000000000..4148780486 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-48.webp new file mode 100644 index 0000000000..50e9565f2d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-64.webp new file mode 100644 index 0000000000..6987a80b12 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-16.webp new file mode 100644 index 0000000000..25e4197507 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-24.webp new file mode 100644 index 0000000000..362dcef435 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-32.webp new file mode 100644 index 0000000000..d39b81c92e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-48.webp new file mode 100644 index 0000000000..a132c7d67b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-64.webp new file mode 100644 index 0000000000..f245084913 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-16.webp new file mode 100644 index 0000000000..47b0b2e11c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-24.webp new file mode 100644 index 0000000000..ba6eed41f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-32.webp new file mode 100644 index 0000000000..700c3c88ad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-48.webp new file mode 100644 index 0000000000..2ff36d6618 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-64.webp new file mode 100644 index 0000000000..23d5ebf7c8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-16.webp new file mode 100644 index 0000000000..75a8e6efee Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-24.webp new file mode 100644 index 0000000000..b84cd5bf0d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-32.webp new file mode 100644 index 0000000000..d8df1a2ba9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-48.webp new file mode 100644 index 0000000000..cc8d14441b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-64.webp new file mode 100644 index 0000000000..e8904c3fec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-16.webp new file mode 100644 index 0000000000..eaa5b13777 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-24.webp new file mode 100644 index 0000000000..93915b6508 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-32.webp new file mode 100644 index 0000000000..0d40e7f604 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-48.webp new file mode 100644 index 0000000000..4d5e6aea3c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-64.webp new file mode 100644 index 0000000000..c425756dd1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-16.webp new file mode 100644 index 0000000000..e95d58db46 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-24.webp new file mode 100644 index 0000000000..38d118e927 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-32.webp new file mode 100644 index 0000000000..de4f1030fd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-48.webp new file mode 100644 index 0000000000..2c3e941061 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-64.webp new file mode 100644 index 0000000000..2586e1a669 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-16.webp new file mode 100644 index 0000000000..7939f2093c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-24.webp new file mode 100644 index 0000000000..59fa3c9eb0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-32.webp new file mode 100644 index 0000000000..a89e5febc6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-48.webp new file mode 100644 index 0000000000..06708c0c3c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-64.webp new file mode 100644 index 0000000000..9c2d9212a4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ML-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-16.webp new file mode 100644 index 0000000000..e06e34770a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-24.webp new file mode 100644 index 0000000000..a9fbce8ed5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-32.webp new file mode 100644 index 0000000000..8a8569538f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-48.webp new file mode 100644 index 0000000000..289d9c34bc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-64.webp new file mode 100644 index 0000000000..7af78dd385 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-16.webp new file mode 100644 index 0000000000..7c42b476d2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-24.webp new file mode 100644 index 0000000000..c6068af3fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-32.webp new file mode 100644 index 0000000000..05bfe8c426 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-48.webp new file mode 100644 index 0000000000..4824f5e2f6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-64.webp new file mode 100644 index 0000000000..63ee116744 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-16.webp new file mode 100644 index 0000000000..d54733a3d7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-24.webp new file mode 100644 index 0000000000..ea907c1452 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-32.webp new file mode 100644 index 0000000000..37ef6ad18c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-48.webp new file mode 100644 index 0000000000..def57393bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-64.webp new file mode 100644 index 0000000000..6013b862db Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-16.webp new file mode 100644 index 0000000000..ea0167460d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-24.webp new file mode 100644 index 0000000000..0d36c221a2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-32.webp new file mode 100644 index 0000000000..67f35d31ef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-48.webp new file mode 100644 index 0000000000..694aaa4a78 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-64.webp new file mode 100644 index 0000000000..26d16bda45 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-16.webp new file mode 100644 index 0000000000..5e04ef54c8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-24.webp new file mode 100644 index 0000000000..faa380a9da Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-32.webp new file mode 100644 index 0000000000..bf5622421c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-48.webp new file mode 100644 index 0000000000..41048139f0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-64.webp new file mode 100644 index 0000000000..deab27eb34 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-16.webp new file mode 100644 index 0000000000..6220d824c4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-24.webp new file mode 100644 index 0000000000..2991464917 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-32.webp new file mode 100644 index 0000000000..3f1fe12a63 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-48.webp new file mode 100644 index 0000000000..a24cfd8d00 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-64.webp new file mode 100644 index 0000000000..5f6603fcb9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-16.webp new file mode 100644 index 0000000000..7f36f7c089 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-24.webp new file mode 100644 index 0000000000..74121e3f73 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-32.webp new file mode 100644 index 0000000000..ac953d9783 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-48.webp new file mode 100644 index 0000000000..99b661dd77 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-64.webp new file mode 100644 index 0000000000..7eb832cac0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-16.webp new file mode 100644 index 0000000000..d052a8d888 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-24.webp new file mode 100644 index 0000000000..a6e6ad7728 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-32.webp new file mode 100644 index 0000000000..8b6f7b52f5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-48.webp new file mode 100644 index 0000000000..ccebd2c189 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-64.webp new file mode 100644 index 0000000000..4e0ad09e6b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MP-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-16.webp new file mode 100644 index 0000000000..8b8c4dc7d5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-24.webp new file mode 100644 index 0000000000..9a218bad3c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-32.webp new file mode 100644 index 0000000000..2eb1bddb0b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-48.webp new file mode 100644 index 0000000000..5e85d849ab Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-64.webp new file mode 100644 index 0000000000..94a9bfeb5c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-16.webp new file mode 100644 index 0000000000..043872854c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-24.webp new file mode 100644 index 0000000000..0c56171a7b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-32.webp new file mode 100644 index 0000000000..598629bc78 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-48.webp new file mode 100644 index 0000000000..eef46bdacc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-64.webp new file mode 100644 index 0000000000..08861f113d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MQ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-16.webp new file mode 100644 index 0000000000..abdf515120 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-24.webp new file mode 100644 index 0000000000..a83ddb7848 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-32.webp new file mode 100644 index 0000000000..22eb40d53e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-48.webp new file mode 100644 index 0000000000..3e6e1fad92 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-64.webp new file mode 100644 index 0000000000..538dd5dcd2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-16.webp new file mode 100644 index 0000000000..925bd52338 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-24.webp new file mode 100644 index 0000000000..024cd552ac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-32.webp new file mode 100644 index 0000000000..563d011bca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-48.webp new file mode 100644 index 0000000000..6cdcafacb5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-64.webp new file mode 100644 index 0000000000..7aa2e9bdd9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-16.webp new file mode 100644 index 0000000000..ecfb28d3f0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-24.webp new file mode 100644 index 0000000000..ec027dc8bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-32.webp new file mode 100644 index 0000000000..d248e27f9a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-48.webp new file mode 100644 index 0000000000..131ec95e9a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-64.webp new file mode 100644 index 0000000000..2bc996de1f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-16.webp new file mode 100644 index 0000000000..0d9dd1634f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-24.webp new file mode 100644 index 0000000000..c59d66f20f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-32.webp new file mode 100644 index 0000000000..07fc7cf957 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-48.webp new file mode 100644 index 0000000000..6ada76a7f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-64.webp new file mode 100644 index 0000000000..a3c89c823d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-16.webp new file mode 100644 index 0000000000..062021621c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-24.webp new file mode 100644 index 0000000000..85609e55e3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-32.webp new file mode 100644 index 0000000000..02f32d9e21 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-48.webp new file mode 100644 index 0000000000..15bf4ef0d4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-64.webp new file mode 100644 index 0000000000..c7ff36c014 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-16.webp new file mode 100644 index 0000000000..777452d3b1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-24.webp new file mode 100644 index 0000000000..2a1f3572ce Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-32.webp new file mode 100644 index 0000000000..bbe6e16609 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-48.webp new file mode 100644 index 0000000000..fab6cb6054 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-64.webp new file mode 100644 index 0000000000..5b00769f65 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-16.webp new file mode 100644 index 0000000000..20d043fc73 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-24.webp new file mode 100644 index 0000000000..6b3951d352 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-32.webp new file mode 100644 index 0000000000..083f4f348f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-48.webp new file mode 100644 index 0000000000..b77d3d2a1c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-64.webp new file mode 100644 index 0000000000..af2abd2811 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-16.webp new file mode 100644 index 0000000000..a299304e9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-24.webp new file mode 100644 index 0000000000..7afc6f2c24 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-32.webp new file mode 100644 index 0000000000..11f5bf22d4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-48.webp new file mode 100644 index 0000000000..b8e8c9c21c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-64.webp new file mode 100644 index 0000000000..bd5db78318 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-16.webp new file mode 100644 index 0000000000..7f15c730ec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-24.webp new file mode 100644 index 0000000000..6b5c42cd06 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-32.webp new file mode 100644 index 0000000000..619f3cac95 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-48.webp new file mode 100644 index 0000000000..a2c8cd44c5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-64.webp new file mode 100644 index 0000000000..8e3bf78f74 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-16.webp new file mode 100644 index 0000000000..7d02c9b66c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-24.webp new file mode 100644 index 0000000000..21693e0d1c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-32.webp new file mode 100644 index 0000000000..07126a6fc1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-48.webp new file mode 100644 index 0000000000..52bf444d44 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-64.webp new file mode 100644 index 0000000000..de2cf60329 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MV-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-16.webp new file mode 100644 index 0000000000..599a04f3e8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-24.webp new file mode 100644 index 0000000000..9fbe52df77 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-32.webp new file mode 100644 index 0000000000..2499041f4e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-48.webp new file mode 100644 index 0000000000..850ad2803b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-64.webp new file mode 100644 index 0000000000..4859e230a8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-16.webp new file mode 100644 index 0000000000..a3d54b9e99 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-24.webp new file mode 100644 index 0000000000..92cc1d824a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-32.webp new file mode 100644 index 0000000000..cac07d26f5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-48.webp new file mode 100644 index 0000000000..2517628eb3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-64.webp new file mode 100644 index 0000000000..bd9fd9f255 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-16.webp new file mode 100644 index 0000000000..1527bc7176 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-24.webp new file mode 100644 index 0000000000..c49e8786b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-32.webp new file mode 100644 index 0000000000..15398b1f4e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-48.webp new file mode 100644 index 0000000000..4f4890b2d2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-64.webp new file mode 100644 index 0000000000..b882de1ced Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-16.webp new file mode 100644 index 0000000000..42c51661b1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-24.webp new file mode 100644 index 0000000000..225795e540 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-32.webp new file mode 100644 index 0000000000..94005113c8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-48.webp new file mode 100644 index 0000000000..771e6c0516 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-64.webp new file mode 100644 index 0000000000..2354c77e06 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MX-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-16.webp new file mode 100644 index 0000000000..62280b93ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-24.webp new file mode 100644 index 0000000000..bd6cc90d6e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-32.webp new file mode 100644 index 0000000000..7b4575a249 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-48.webp new file mode 100644 index 0000000000..2f98811522 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-64.webp new file mode 100644 index 0000000000..b8575b49d4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-16.webp new file mode 100644 index 0000000000..b7a6cd4cfb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-24.webp new file mode 100644 index 0000000000..693f85bd31 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-32.webp new file mode 100644 index 0000000000..a7c67489d7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-48.webp new file mode 100644 index 0000000000..61934d83e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-64.webp new file mode 100644 index 0000000000..fbf3b326d4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-16.webp new file mode 100644 index 0000000000..ae79ce0815 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-24.webp new file mode 100644 index 0000000000..5f2dc8f21b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-32.webp new file mode 100644 index 0000000000..8b1c7f4075 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-48.webp new file mode 100644 index 0000000000..9c6f9307d9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-64.webp new file mode 100644 index 0000000000..8e6da917c3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-16.webp new file mode 100644 index 0000000000..defb4ec352 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-24.webp new file mode 100644 index 0000000000..54d0f0afb8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-32.webp new file mode 100644 index 0000000000..0f88fe51ea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-48.webp new file mode 100644 index 0000000000..57519d08b3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-64.webp new file mode 100644 index 0000000000..920729d845 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/MZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-16.webp new file mode 100644 index 0000000000..134dfd2475 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-24.webp new file mode 100644 index 0000000000..9dc7eb2ff3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-32.webp new file mode 100644 index 0000000000..ab8e2ec759 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-48.webp new file mode 100644 index 0000000000..38dbd762a4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-64.webp new file mode 100644 index 0000000000..4c9cb5fe2c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-16.webp new file mode 100644 index 0000000000..8735c658a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-24.webp new file mode 100644 index 0000000000..b4b46efef6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-32.webp new file mode 100644 index 0000000000..3c47303cb3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-48.webp new file mode 100644 index 0000000000..da80c2b791 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-64.webp new file mode 100644 index 0000000000..bad1f10ae9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-16.webp new file mode 100644 index 0000000000..974035d32e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-24.webp new file mode 100644 index 0000000000..1734aade47 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-32.webp new file mode 100644 index 0000000000..cd1790197b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-48.webp new file mode 100644 index 0000000000..fe3cb3024c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-64.webp new file mode 100644 index 0000000000..396a674054 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-16.webp new file mode 100644 index 0000000000..1a44189b9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-24.webp new file mode 100644 index 0000000000..2ea70829d9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-32.webp new file mode 100644 index 0000000000..7fd3c61aaa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-48.webp new file mode 100644 index 0000000000..046223b78b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-64.webp new file mode 100644 index 0000000000..075515e052 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NC-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-16.webp new file mode 100644 index 0000000000..e84cb44c29 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-24.webp new file mode 100644 index 0000000000..25c36b3b3e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-32.webp new file mode 100644 index 0000000000..9a60eb8149 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-48.webp new file mode 100644 index 0000000000..f272b83e20 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-64.webp new file mode 100644 index 0000000000..f59cccba4a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-16.webp new file mode 100644 index 0000000000..969ac68a1b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-24.webp new file mode 100644 index 0000000000..148391b341 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-32.webp new file mode 100644 index 0000000000..4cc9869cae Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-48.webp new file mode 100644 index 0000000000..a36ddda4ba Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-64.webp new file mode 100644 index 0000000000..22c4137080 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-16.webp new file mode 100644 index 0000000000..8b5496e0d0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-24.webp new file mode 100644 index 0000000000..20406b4fa6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-32.webp new file mode 100644 index 0000000000..de43c12d96 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-48.webp new file mode 100644 index 0000000000..5e0701e049 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-64.webp new file mode 100644 index 0000000000..cd3359f33e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-16.webp new file mode 100644 index 0000000000..7b67808180 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-24.webp new file mode 100644 index 0000000000..2f74e9dcd9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-32.webp new file mode 100644 index 0000000000..ae00ae594b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-48.webp new file mode 100644 index 0000000000..6db69582ce Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-64.webp new file mode 100644 index 0000000000..a553a668c1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NF-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-16.webp new file mode 100644 index 0000000000..2d67f3325a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-24.webp new file mode 100644 index 0000000000..bf3d3113d8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-32.webp new file mode 100644 index 0000000000..5639474030 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-48.webp new file mode 100644 index 0000000000..a28c115ae8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-64.webp new file mode 100644 index 0000000000..90b58f0787 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-16.webp new file mode 100644 index 0000000000..099918b561 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-24.webp new file mode 100644 index 0000000000..c5e30d0332 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-32.webp new file mode 100644 index 0000000000..9289af3c4b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-48.webp new file mode 100644 index 0000000000..2200355623 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-64.webp new file mode 100644 index 0000000000..982a914be1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-16.webp new file mode 100644 index 0000000000..faf27c5b63 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-24.webp new file mode 100644 index 0000000000..204ed67512 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-32.webp new file mode 100644 index 0000000000..0f5f0bbc89 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-48.webp new file mode 100644 index 0000000000..cfb12c5db8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-64.webp new file mode 100644 index 0000000000..e6aaa5bb4f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-16.webp new file mode 100644 index 0000000000..0fcfa0355f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-24.webp new file mode 100644 index 0000000000..1b6c608985 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-32.webp new file mode 100644 index 0000000000..103c22f1f3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-48.webp new file mode 100644 index 0000000000..de4e92f991 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-64.webp new file mode 100644 index 0000000000..6394239e71 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-16.webp new file mode 100644 index 0000000000..1ba676b9ce Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-24.webp new file mode 100644 index 0000000000..71518dbf5f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-32.webp new file mode 100644 index 0000000000..abf42ce679 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-48.webp new file mode 100644 index 0000000000..7fc1add744 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-64.webp new file mode 100644 index 0000000000..5962cd0c15 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-16.webp new file mode 100644 index 0000000000..2c5c31f201 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-24.webp new file mode 100644 index 0000000000..0cb48ee07f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-32.webp new file mode 100644 index 0000000000..2e2f4ebd6f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-48.webp new file mode 100644 index 0000000000..26c359f0f7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-64.webp new file mode 100644 index 0000000000..82827de835 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NL-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-16.webp new file mode 100644 index 0000000000..5451cf9b51 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-24.webp new file mode 100644 index 0000000000..e61e67aa61 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-32.webp new file mode 100644 index 0000000000..50a0464ec6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-48.webp new file mode 100644 index 0000000000..9554359feb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-64.webp new file mode 100644 index 0000000000..4081adbca3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-16.webp new file mode 100644 index 0000000000..27ebd00c9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-24.webp new file mode 100644 index 0000000000..8f8704de0d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-32.webp new file mode 100644 index 0000000000..40dfa91243 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-48.webp new file mode 100644 index 0000000000..04f2cf56c8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-64.webp new file mode 100644 index 0000000000..b5c9ba04ff Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-16.webp new file mode 100644 index 0000000000..ef3cbbbf38 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-24.webp new file mode 100644 index 0000000000..41e65e7747 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-32.webp new file mode 100644 index 0000000000..342fe4a9f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-48.webp new file mode 100644 index 0000000000..c943e26cc4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-64.webp new file mode 100644 index 0000000000..f8ec1838bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-16.webp new file mode 100644 index 0000000000..8d6ef53347 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-24.webp new file mode 100644 index 0000000000..dc10f5a026 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-32.webp new file mode 100644 index 0000000000..202e4c9209 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-48.webp new file mode 100644 index 0000000000..7d4f0a3ed7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-64.webp new file mode 100644 index 0000000000..977eedeac2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NP-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-16.webp new file mode 100644 index 0000000000..a768662a63 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-24.webp new file mode 100644 index 0000000000..49648c28a8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-32.webp new file mode 100644 index 0000000000..016d9cc43d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-48.webp new file mode 100644 index 0000000000..1f6228a4e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-64.webp new file mode 100644 index 0000000000..ad925e0294 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-16.webp new file mode 100644 index 0000000000..d1f7bab00f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-24.webp new file mode 100644 index 0000000000..f0a5921240 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-32.webp new file mode 100644 index 0000000000..ec3cce9c03 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-48.webp new file mode 100644 index 0000000000..02f79251ea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-64.webp new file mode 100644 index 0000000000..606fb0c033 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-16.webp new file mode 100644 index 0000000000..ee19b0601c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-24.webp new file mode 100644 index 0000000000..59c173f219 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-32.webp new file mode 100644 index 0000000000..4146574b3d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-48.webp new file mode 100644 index 0000000000..2824376ef2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-64.webp new file mode 100644 index 0000000000..bbdb2c36f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-16.webp new file mode 100644 index 0000000000..f43ab588f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-24.webp new file mode 100644 index 0000000000..74c7c184b3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-32.webp new file mode 100644 index 0000000000..47435fe014 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-48.webp new file mode 100644 index 0000000000..139947830c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-64.webp new file mode 100644 index 0000000000..a6472cee46 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-16.webp new file mode 100644 index 0000000000..b3f26aee81 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-24.webp new file mode 100644 index 0000000000..cb892ca1fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-32.webp new file mode 100644 index 0000000000..2e15873093 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-48.webp new file mode 100644 index 0000000000..77ad34e155 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-64.webp new file mode 100644 index 0000000000..9cb4201c7f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-16.webp new file mode 100644 index 0000000000..0aa006ba06 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-24.webp new file mode 100644 index 0000000000..6acc6e3317 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-32.webp new file mode 100644 index 0000000000..353bd39a3c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-48.webp new file mode 100644 index 0000000000..3ec98ddbe3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-64.webp new file mode 100644 index 0000000000..5225f3296c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/NZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-16.webp new file mode 100644 index 0000000000..f75692de9a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-24.webp new file mode 100644 index 0000000000..df72e2b06c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-32.webp new file mode 100644 index 0000000000..0f566f531a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-48.webp new file mode 100644 index 0000000000..cf94abdac0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-64.webp new file mode 100644 index 0000000000..bd841bc9a1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-16.webp new file mode 100644 index 0000000000..57ee540d40 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-24.webp new file mode 100644 index 0000000000..3b7d3054eb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-32.webp new file mode 100644 index 0000000000..919568bf13 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-48.webp new file mode 100644 index 0000000000..5cebade2bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-64.webp new file mode 100644 index 0000000000..40201931a3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/OM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-16.webp new file mode 100644 index 0000000000..1740cf93b6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-24.webp new file mode 100644 index 0000000000..07322c4f49 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-32.webp new file mode 100644 index 0000000000..05ea95979f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-48.webp new file mode 100644 index 0000000000..3fa5a2b10c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-64.webp new file mode 100644 index 0000000000..963676a76e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-16.webp new file mode 100644 index 0000000000..fff12d12e6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-24.webp new file mode 100644 index 0000000000..52cf3a40a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-32.webp new file mode 100644 index 0000000000..af70b71642 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-48.webp new file mode 100644 index 0000000000..8602b031a2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-64.webp new file mode 100644 index 0000000000..d3bfa2c5ae Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-16.webp new file mode 100644 index 0000000000..682f2684c1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-24.webp new file mode 100644 index 0000000000..ddb29804a1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-32.webp new file mode 100644 index 0000000000..bf8e607ada Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-48.webp new file mode 100644 index 0000000000..cbad1e2ae5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-64.webp new file mode 100644 index 0000000000..731a2bb5f9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-16.webp new file mode 100644 index 0000000000..b8ef3a2ee4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-24.webp new file mode 100644 index 0000000000..d7d6060b9a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-32.webp new file mode 100644 index 0000000000..4c45b5f0b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-48.webp new file mode 100644 index 0000000000..7f76d55eac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-64.webp new file mode 100644 index 0000000000..8e537f6ec2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-16.webp new file mode 100644 index 0000000000..77914f8e91 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-24.webp new file mode 100644 index 0000000000..2a04221488 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-32.webp new file mode 100644 index 0000000000..c36c31613a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-48.webp new file mode 100644 index 0000000000..ce23d323bc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-64.webp new file mode 100644 index 0000000000..34a4135eda Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-16.webp new file mode 100644 index 0000000000..9df7159681 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-24.webp new file mode 100644 index 0000000000..00f2050134 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-32.webp new file mode 100644 index 0000000000..4515c593bb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-48.webp new file mode 100644 index 0000000000..8d9d621069 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-64.webp new file mode 100644 index 0000000000..e012e67a9e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PF-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-16.webp new file mode 100644 index 0000000000..dd87a7d046 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-24.webp new file mode 100644 index 0000000000..ca725f9bd1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-32.webp new file mode 100644 index 0000000000..975daaa4a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-48.webp new file mode 100644 index 0000000000..b8c2762651 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-64.webp new file mode 100644 index 0000000000..673b61eeaa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-16.webp new file mode 100644 index 0000000000..2696357ad6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-24.webp new file mode 100644 index 0000000000..4918d896e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-32.webp new file mode 100644 index 0000000000..66102aa8d9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-48.webp new file mode 100644 index 0000000000..a1658c1717 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-64.webp new file mode 100644 index 0000000000..364f9ec02f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-16.webp new file mode 100644 index 0000000000..a29d5fbaab Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-24.webp new file mode 100644 index 0000000000..e2b7fcb332 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-32.webp new file mode 100644 index 0000000000..587a048a85 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-48.webp new file mode 100644 index 0000000000..3af24ca231 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-64.webp new file mode 100644 index 0000000000..212773c967 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-16.webp new file mode 100644 index 0000000000..5ddedc1199 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-24.webp new file mode 100644 index 0000000000..ceed21ac1c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-32.webp new file mode 100644 index 0000000000..fb8ea54302 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-48.webp new file mode 100644 index 0000000000..0d60c2dd3c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-64.webp new file mode 100644 index 0000000000..262a3eaf80 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-16.webp new file mode 100644 index 0000000000..bdb7943c77 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-24.webp new file mode 100644 index 0000000000..122b7a04e7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-32.webp new file mode 100644 index 0000000000..5ee81885fb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-48.webp new file mode 100644 index 0000000000..295d3532c3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-64.webp new file mode 100644 index 0000000000..e4683e7446 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-16.webp new file mode 100644 index 0000000000..afad47c9ff Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-24.webp new file mode 100644 index 0000000000..e99b205d44 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-32.webp new file mode 100644 index 0000000000..cbf8c4b78e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-48.webp new file mode 100644 index 0000000000..5905739411 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-64.webp new file mode 100644 index 0000000000..8cb02796c3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-16.webp new file mode 100644 index 0000000000..01d71d931e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-24.webp new file mode 100644 index 0000000000..8f607e80cf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-32.webp new file mode 100644 index 0000000000..64714542b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-48.webp new file mode 100644 index 0000000000..f8cb5fb02a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-64.webp new file mode 100644 index 0000000000..c31da9c30c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-16.webp new file mode 100644 index 0000000000..4f0a299157 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-24.webp new file mode 100644 index 0000000000..df222ec7e5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-32.webp new file mode 100644 index 0000000000..74f013cd0e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-48.webp new file mode 100644 index 0000000000..c20a466c06 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-64.webp new file mode 100644 index 0000000000..d80b8142fc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PL-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-16.webp new file mode 100644 index 0000000000..326bb9d330 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-24.webp new file mode 100644 index 0000000000..7b1f7b5838 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-32.webp new file mode 100644 index 0000000000..f9710e049a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-48.webp new file mode 100644 index 0000000000..aa1606e421 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-64.webp new file mode 100644 index 0000000000..ab4c356d93 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-16.webp new file mode 100644 index 0000000000..82e8962bc9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-24.webp new file mode 100644 index 0000000000..cd3a0077bc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-32.webp new file mode 100644 index 0000000000..178ef6f35f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-48.webp new file mode 100644 index 0000000000..fec5f7c67f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-64.webp new file mode 100644 index 0000000000..1ddf8f79a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-16.webp new file mode 100644 index 0000000000..b401a19264 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-24.webp new file mode 100644 index 0000000000..6c4cad538b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-32.webp new file mode 100644 index 0000000000..88c166dd5b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-48.webp new file mode 100644 index 0000000000..459484ff48 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-64.webp new file mode 100644 index 0000000000..3573a01ea7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-16.webp new file mode 100644 index 0000000000..37e81bebfa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-24.webp new file mode 100644 index 0000000000..de83549f5d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-32.webp new file mode 100644 index 0000000000..c0cf9a17e3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-48.webp new file mode 100644 index 0000000000..51710f58cd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-64.webp new file mode 100644 index 0000000000..11165d664f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-16.webp new file mode 100644 index 0000000000..a4ca25a32a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-24.webp new file mode 100644 index 0000000000..4494d0c7dd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-32.webp new file mode 100644 index 0000000000..9defa97b17 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-48.webp new file mode 100644 index 0000000000..98dbfc437e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-64.webp new file mode 100644 index 0000000000..8793c87cda Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-16.webp new file mode 100644 index 0000000000..078f4c80ec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-24.webp new file mode 100644 index 0000000000..e49e8cfe1a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-32.webp new file mode 100644 index 0000000000..6d5ec064e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-48.webp new file mode 100644 index 0000000000..c56329d3cf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-64.webp new file mode 100644 index 0000000000..0b111d2443 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-16.webp new file mode 100644 index 0000000000..fc1ad100da Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-24.webp new file mode 100644 index 0000000000..d3aed8cb62 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-32.webp new file mode 100644 index 0000000000..975d417226 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-48.webp new file mode 100644 index 0000000000..c4ad179d14 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-64.webp new file mode 100644 index 0000000000..d0a9cf876b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-16.webp new file mode 100644 index 0000000000..6b0c5b402a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-24.webp new file mode 100644 index 0000000000..1a56572e13 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-32.webp new file mode 100644 index 0000000000..96c361fde2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-48.webp new file mode 100644 index 0000000000..b9343dfca0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-64.webp new file mode 100644 index 0000000000..0aebcb2829 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-16.webp new file mode 100644 index 0000000000..28b89bbfb8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-24.webp new file mode 100644 index 0000000000..62c9d873fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-32.webp new file mode 100644 index 0000000000..a9473de2a0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-48.webp new file mode 100644 index 0000000000..163ecd126f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-64.webp new file mode 100644 index 0000000000..9e90936898 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-16.webp new file mode 100644 index 0000000000..08687a9238 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-24.webp new file mode 100644 index 0000000000..fe0c34deae Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-32.webp new file mode 100644 index 0000000000..46a7928209 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-48.webp new file mode 100644 index 0000000000..63020ad5f8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-64.webp new file mode 100644 index 0000000000..96a4b3c6e8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-16.webp new file mode 100644 index 0000000000..f420afc55a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-24.webp new file mode 100644 index 0000000000..5c5eee097c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-32.webp new file mode 100644 index 0000000000..fe5db69949 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-48.webp new file mode 100644 index 0000000000..e948e26c5b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-64.webp new file mode 100644 index 0000000000..4bda5016f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-16.webp new file mode 100644 index 0000000000..eb1eb8269d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-24.webp new file mode 100644 index 0000000000..c699ffb32f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-32.webp new file mode 100644 index 0000000000..1ef902c8ea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-48.webp new file mode 100644 index 0000000000..038d47106f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-64.webp new file mode 100644 index 0000000000..99e97cf4f7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/PY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-16.webp new file mode 100644 index 0000000000..33dddf2456 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-24.webp new file mode 100644 index 0000000000..002bd2caf1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-32.webp new file mode 100644 index 0000000000..75abf1e788 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-48.webp new file mode 100644 index 0000000000..e9522593ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-64.webp new file mode 100644 index 0000000000..31a4a4d875 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-16.webp new file mode 100644 index 0000000000..0126d8c5e7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-24.webp new file mode 100644 index 0000000000..d6d04360ca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-32.webp new file mode 100644 index 0000000000..d2e470e5c9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-48.webp new file mode 100644 index 0000000000..aa8d4e7b49 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-64.webp new file mode 100644 index 0000000000..cb1add0b6f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/QA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-16.webp new file mode 100644 index 0000000000..086283a9af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-24.webp new file mode 100644 index 0000000000..2c54dcbe46 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-32.webp new file mode 100644 index 0000000000..0360f7d444 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-48.webp new file mode 100644 index 0000000000..b2b0b7cfe5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-64.webp new file mode 100644 index 0000000000..6e0d730072 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-16.webp new file mode 100644 index 0000000000..fc70662e89 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-24.webp new file mode 100644 index 0000000000..99181919a2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-32.webp new file mode 100644 index 0000000000..aa96709217 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-48.webp new file mode 100644 index 0000000000..71246ab89c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-64.webp new file mode 100644 index 0000000000..e47d141746 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-16.webp new file mode 100644 index 0000000000..ddf7a46d6f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-24.webp new file mode 100644 index 0000000000..a983c1647d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-32.webp new file mode 100644 index 0000000000..9052778eb7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-48.webp new file mode 100644 index 0000000000..f00160d6bc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-64.webp new file mode 100644 index 0000000000..e96520d4af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-16.webp new file mode 100644 index 0000000000..c5ca3c8f49 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-24.webp new file mode 100644 index 0000000000..9fd95c1921 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-32.webp new file mode 100644 index 0000000000..0eb4c915af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-48.webp new file mode 100644 index 0000000000..277add13b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-64.webp new file mode 100644 index 0000000000..68a944dfaa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-16.webp new file mode 100644 index 0000000000..71bce8157f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-24.webp new file mode 100644 index 0000000000..b017dab77c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-32.webp new file mode 100644 index 0000000000..3c7315d204 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-48.webp new file mode 100644 index 0000000000..748bf3bdb7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-64.webp new file mode 100644 index 0000000000..9a4989abd7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-16.webp new file mode 100644 index 0000000000..e0c11a5e8b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-24.webp new file mode 100644 index 0000000000..98c74541f4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-32.webp new file mode 100644 index 0000000000..9b661dda01 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-48.webp new file mode 100644 index 0000000000..d63768d851 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-64.webp new file mode 100644 index 0000000000..e62022e6ca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-16.webp new file mode 100644 index 0000000000..3f9b368013 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-24.webp new file mode 100644 index 0000000000..7ae0c64b58 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-32.webp new file mode 100644 index 0000000000..da27d11835 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-48.webp new file mode 100644 index 0000000000..f0acdd3051 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-64.webp new file mode 100644 index 0000000000..f455064d26 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-16.webp new file mode 100644 index 0000000000..740a407002 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-24.webp new file mode 100644 index 0000000000..84f1d930e7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-32.webp new file mode 100644 index 0000000000..41b0ce854d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-48.webp new file mode 100644 index 0000000000..93857e993b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-64.webp new file mode 100644 index 0000000000..5f33424358 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-16.webp new file mode 100644 index 0000000000..35cea0674b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-24.webp new file mode 100644 index 0000000000..bfd22abe47 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-32.webp new file mode 100644 index 0000000000..5ad45c62e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-48.webp new file mode 100644 index 0000000000..6678893342 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-64.webp new file mode 100644 index 0000000000..0e9e147563 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-16.webp new file mode 100644 index 0000000000..09ab3605d6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-24.webp new file mode 100644 index 0000000000..02ff6b711e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-32.webp new file mode 100644 index 0000000000..6360e30145 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-48.webp new file mode 100644 index 0000000000..43ce30ad42 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-64.webp new file mode 100644 index 0000000000..ce183e88ad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/RW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-16.webp new file mode 100644 index 0000000000..0741f13e12 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-24.webp new file mode 100644 index 0000000000..5560885277 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-32.webp new file mode 100644 index 0000000000..fee5ad1382 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-48.webp new file mode 100644 index 0000000000..2c3a539619 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-64.webp new file mode 100644 index 0000000000..37e6264bf5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-16.webp new file mode 100644 index 0000000000..40609cc213 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-24.webp new file mode 100644 index 0000000000..a59ce49090 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-32.webp new file mode 100644 index 0000000000..ae952fee97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-48.webp new file mode 100644 index 0000000000..2c4c30fd2e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-64.webp new file mode 100644 index 0000000000..797b3474b5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-16.webp new file mode 100644 index 0000000000..f75d8af959 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-24.webp new file mode 100644 index 0000000000..20328d72af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-32.webp new file mode 100644 index 0000000000..4c18ece510 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-48.webp new file mode 100644 index 0000000000..02dbd562a6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-64.webp new file mode 100644 index 0000000000..84c5bbe0b7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-16.webp new file mode 100644 index 0000000000..982ec00ed0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-24.webp new file mode 100644 index 0000000000..7a43237947 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-32.webp new file mode 100644 index 0000000000..1e70cf6d1b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-48.webp new file mode 100644 index 0000000000..7f11ec23fa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-64.webp new file mode 100644 index 0000000000..51e1d533dc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SB-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-16.webp new file mode 100644 index 0000000000..aadf39b7a9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-24.webp new file mode 100644 index 0000000000..e2815e0c82 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-32.webp new file mode 100644 index 0000000000..2ca2c858d9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-48.webp new file mode 100644 index 0000000000..9ce4f010cf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-64.webp new file mode 100644 index 0000000000..eb6c0652ac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-16.webp new file mode 100644 index 0000000000..3f3130a57b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-24.webp new file mode 100644 index 0000000000..6881c0c331 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-32.webp new file mode 100644 index 0000000000..47cd68ea92 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-48.webp new file mode 100644 index 0000000000..05facc7f34 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-64.webp new file mode 100644 index 0000000000..99194258e0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SC-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-16.webp new file mode 100644 index 0000000000..2172dd833f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-24.webp new file mode 100644 index 0000000000..e09b629ff8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-32.webp new file mode 100644 index 0000000000..be97b434ad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-48.webp new file mode 100644 index 0000000000..91c7fc8749 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-64.webp new file mode 100644 index 0000000000..d907226384 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-16.webp new file mode 100644 index 0000000000..21d2d7dbc1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-24.webp new file mode 100644 index 0000000000..da98e3bfc5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-32.webp new file mode 100644 index 0000000000..23b2c3338e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-48.webp new file mode 100644 index 0000000000..d699ba0bb3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-64.webp new file mode 100644 index 0000000000..bd5bbea0e5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SD-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-16.webp new file mode 100644 index 0000000000..4ef5957459 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-24.webp new file mode 100644 index 0000000000..9021fb3b02 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-32.webp new file mode 100644 index 0000000000..dd43accf89 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-48.webp new file mode 100644 index 0000000000..5ed877c506 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-64.webp new file mode 100644 index 0000000000..fbe370c27a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-16.webp new file mode 100644 index 0000000000..d2cf329dc0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-24.webp new file mode 100644 index 0000000000..e6d0fa1a66 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-32.webp new file mode 100644 index 0000000000..85aa7e673c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-48.webp new file mode 100644 index 0000000000..405c994fa6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-64.webp new file mode 100644 index 0000000000..684ba61b7a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-16.webp new file mode 100644 index 0000000000..ffdd8fd337 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-24.webp new file mode 100644 index 0000000000..0cde929ea8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-32.webp new file mode 100644 index 0000000000..2a601b2647 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-48.webp new file mode 100644 index 0000000000..e43556aad2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-64.webp new file mode 100644 index 0000000000..76ab26f0a1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-16.webp new file mode 100644 index 0000000000..9b0151c884 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-24.webp new file mode 100644 index 0000000000..8bb1905007 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-32.webp new file mode 100644 index 0000000000..8268810d6f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-48.webp new file mode 100644 index 0000000000..13844bd832 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-64.webp new file mode 100644 index 0000000000..7f035435e2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-16.webp new file mode 100644 index 0000000000..4593049e1d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-24.webp new file mode 100644 index 0000000000..e15b3a3d3d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-32.webp new file mode 100644 index 0000000000..fb9b754358 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-48.webp new file mode 100644 index 0000000000..3c1fcc63f9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-64.webp new file mode 100644 index 0000000000..e3bfc70986 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-16.webp new file mode 100644 index 0000000000..f0c03b047c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-24.webp new file mode 100644 index 0000000000..035a50a75b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-32.webp new file mode 100644 index 0000000000..92a0af3108 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-48.webp new file mode 100644 index 0000000000..3e95bdcee3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-64.webp new file mode 100644 index 0000000000..596b62634b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-16.webp new file mode 100644 index 0000000000..05bf1bb17c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-24.webp new file mode 100644 index 0000000000..642f2157de Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-32.webp new file mode 100644 index 0000000000..ba883c4d28 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-48.webp new file mode 100644 index 0000000000..1fa01d5855 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-64.webp new file mode 100644 index 0000000000..890cb74113 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-16.webp new file mode 100644 index 0000000000..55c0f30650 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-24.webp new file mode 100644 index 0000000000..cf48031951 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-32.webp new file mode 100644 index 0000000000..dcee1ac63d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-48.webp new file mode 100644 index 0000000000..377815ce15 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-64.webp new file mode 100644 index 0000000000..9c1a781b5c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-16.webp new file mode 100644 index 0000000000..4f3f128dea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-24.webp new file mode 100644 index 0000000000..7186d5ba84 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-32.webp new file mode 100644 index 0000000000..058ca4647c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-48.webp new file mode 100644 index 0000000000..26b4c22b94 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-64.webp new file mode 100644 index 0000000000..fbb09150ad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-16.webp new file mode 100644 index 0000000000..541c001d9d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-24.webp new file mode 100644 index 0000000000..05f0b018dc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-32.webp new file mode 100644 index 0000000000..76b8b5e7e7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-48.webp new file mode 100644 index 0000000000..13d5a614af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-64.webp new file mode 100644 index 0000000000..3037998050 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-16.webp new file mode 100644 index 0000000000..5c12572210 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-24.webp new file mode 100644 index 0000000000..72db2e606c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-32.webp new file mode 100644 index 0000000000..da905be248 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-48.webp new file mode 100644 index 0000000000..24a5a02719 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-64.webp new file mode 100644 index 0000000000..405d267f1c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-16.webp new file mode 100644 index 0000000000..b081cc2eab Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-24.webp new file mode 100644 index 0000000000..428f50ba34 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-32.webp new file mode 100644 index 0000000000..550e1cf829 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-48.webp new file mode 100644 index 0000000000..c9582ae249 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-64.webp new file mode 100644 index 0000000000..2b58d6254f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SL-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-16.webp new file mode 100644 index 0000000000..5476a57f09 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-24.webp new file mode 100644 index 0000000000..d0468d008e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-32.webp new file mode 100644 index 0000000000..c840dcbb95 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-48.webp new file mode 100644 index 0000000000..548c8381fb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-64.webp new file mode 100644 index 0000000000..a51eb77e56 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-16.webp new file mode 100644 index 0000000000..b6ff4ad6c1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-24.webp new file mode 100644 index 0000000000..c7fdac1a30 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-32.webp new file mode 100644 index 0000000000..06520afc07 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-48.webp new file mode 100644 index 0000000000..744b00b553 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-64.webp new file mode 100644 index 0000000000..3041c28196 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-16.webp new file mode 100644 index 0000000000..2e05e17e7d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-24.webp new file mode 100644 index 0000000000..93b68bedd7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-32.webp new file mode 100644 index 0000000000..49d849ce22 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-48.webp new file mode 100644 index 0000000000..5d924fd0e7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-64.webp new file mode 100644 index 0000000000..7f60e77f7b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-16.webp new file mode 100644 index 0000000000..29177bb859 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-24.webp new file mode 100644 index 0000000000..4995c84ab0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-32.webp new file mode 100644 index 0000000000..eda46d4741 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-48.webp new file mode 100644 index 0000000000..ff991debc3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-64.webp new file mode 100644 index 0000000000..492c0d89ec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-16.webp new file mode 100644 index 0000000000..6dd9614b09 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-24.webp new file mode 100644 index 0000000000..1a69156c88 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-32.webp new file mode 100644 index 0000000000..c6bd73b1ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-48.webp new file mode 100644 index 0000000000..a028094b9d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-64.webp new file mode 100644 index 0000000000..1023834690 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-16.webp new file mode 100644 index 0000000000..27993050c9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-24.webp new file mode 100644 index 0000000000..1805c1c7fb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-32.webp new file mode 100644 index 0000000000..a91826c65c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-48.webp new file mode 100644 index 0000000000..acf56ea459 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-64.webp new file mode 100644 index 0000000000..b5327a8f85 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-16.webp new file mode 100644 index 0000000000..62999fec99 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-24.webp new file mode 100644 index 0000000000..53691e6041 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-32.webp new file mode 100644 index 0000000000..1ab1e33fb9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-48.webp new file mode 100644 index 0000000000..f3b0d15659 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-64.webp new file mode 100644 index 0000000000..d249280e66 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-16.webp new file mode 100644 index 0000000000..33fd458382 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-24.webp new file mode 100644 index 0000000000..f693345f24 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-32.webp new file mode 100644 index 0000000000..9452ea07b7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-48.webp new file mode 100644 index 0000000000..f10c87b08e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-64.webp new file mode 100644 index 0000000000..8a9cc336e0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-16.webp new file mode 100644 index 0000000000..38d3bbba91 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-24.webp new file mode 100644 index 0000000000..174e2ea73e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-32.webp new file mode 100644 index 0000000000..9ac529aee8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-48.webp new file mode 100644 index 0000000000..58b68c7c69 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-64.webp new file mode 100644 index 0000000000..03728fcdcd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-16.webp new file mode 100644 index 0000000000..da61aae208 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-24.webp new file mode 100644 index 0000000000..c9c1710e58 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-32.webp new file mode 100644 index 0000000000..682cb235e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-48.webp new file mode 100644 index 0000000000..8b8fe7b32a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-64.webp new file mode 100644 index 0000000000..f4e4a5b84b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-16.webp new file mode 100644 index 0000000000..24063c1bfd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-24.webp new file mode 100644 index 0000000000..4415487a3d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-32.webp new file mode 100644 index 0000000000..4f8d9b910f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-48.webp new file mode 100644 index 0000000000..61503feeda Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-64.webp new file mode 100644 index 0000000000..2f1205f7bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-16.webp new file mode 100644 index 0000000000..241291033a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-24.webp new file mode 100644 index 0000000000..cf49f4af6a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-32.webp new file mode 100644 index 0000000000..3490e45a2a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-48.webp new file mode 100644 index 0000000000..9ac3070bc5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-64.webp new file mode 100644 index 0000000000..527bf8c516 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ST-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-16.webp new file mode 100644 index 0000000000..681f516f8f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-24.webp new file mode 100644 index 0000000000..91fa01edd2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-32.webp new file mode 100644 index 0000000000..020c736062 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-48.webp new file mode 100644 index 0000000000..f821f9e8a2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-64.webp new file mode 100644 index 0000000000..085284b19a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-16.webp new file mode 100644 index 0000000000..c245e88662 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-24.webp new file mode 100644 index 0000000000..16fcfb0517 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-32.webp new file mode 100644 index 0000000000..9552a5e1df Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-48.webp new file mode 100644 index 0000000000..3bf51fee0b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-64.webp new file mode 100644 index 0000000000..fd9e0d2ee5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SV-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-16.webp new file mode 100644 index 0000000000..379c255a55 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-24.webp new file mode 100644 index 0000000000..9a4055bb77 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-32.webp new file mode 100644 index 0000000000..1a9273d075 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-48.webp new file mode 100644 index 0000000000..e22f43608a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-64.webp new file mode 100644 index 0000000000..f9e044aba9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-16.webp new file mode 100644 index 0000000000..b8865443b4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-24.webp new file mode 100644 index 0000000000..ea70aa5285 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-32.webp new file mode 100644 index 0000000000..3b0705759e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-48.webp new file mode 100644 index 0000000000..868fa3adff Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-64.webp new file mode 100644 index 0000000000..108d8784bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-16.webp new file mode 100644 index 0000000000..ab7727c308 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-24.webp new file mode 100644 index 0000000000..337e511b4a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-32.webp new file mode 100644 index 0000000000..2a5298380b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-48.webp new file mode 100644 index 0000000000..36ff1d11c0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-64.webp new file mode 100644 index 0000000000..ca6e7c7d09 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-16.webp new file mode 100644 index 0000000000..3c1a678a03 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-24.webp new file mode 100644 index 0000000000..fa4e58736d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-32.webp new file mode 100644 index 0000000000..fdf6e5264d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-48.webp new file mode 100644 index 0000000000..b4f0931893 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-64.webp new file mode 100644 index 0000000000..767bda069b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/SZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-16.webp new file mode 100644 index 0000000000..b66ff92f48 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-24.webp new file mode 100644 index 0000000000..093577dafe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-32.webp new file mode 100644 index 0000000000..35b7a7d43e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-48.webp new file mode 100644 index 0000000000..fe4f8a88c6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-64.webp new file mode 100644 index 0000000000..8f3ef6989b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-16.webp new file mode 100644 index 0000000000..c765410daa Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-24.webp new file mode 100644 index 0000000000..042e5a6cff Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-32.webp new file mode 100644 index 0000000000..d0606e2db7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-48.webp new file mode 100644 index 0000000000..0846a52b2a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-64.webp new file mode 100644 index 0000000000..54e6a4cda7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TC-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-16.webp new file mode 100644 index 0000000000..92f3295383 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-24.webp new file mode 100644 index 0000000000..2d6f463fa5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-32.webp new file mode 100644 index 0000000000..b8f9533f52 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-48.webp new file mode 100644 index 0000000000..faaf1a8ffe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-64.webp new file mode 100644 index 0000000000..681f80634d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-16.webp new file mode 100644 index 0000000000..7cb2ec1b00 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-24.webp new file mode 100644 index 0000000000..c155fcaf5d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-32.webp new file mode 100644 index 0000000000..46459cbd7a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-48.webp new file mode 100644 index 0000000000..228cda304b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-64.webp new file mode 100644 index 0000000000..390d40b4b2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TD-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-16.webp new file mode 100644 index 0000000000..7a6a1cbb2c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-24.webp new file mode 100644 index 0000000000..5abc9a3a55 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-32.webp new file mode 100644 index 0000000000..529b12a48d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-48.webp new file mode 100644 index 0000000000..d9bff3b47f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-64.webp new file mode 100644 index 0000000000..cc2f0ad94b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-16.webp new file mode 100644 index 0000000000..ac2165817a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-24.webp new file mode 100644 index 0000000000..d59cd05dbd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-32.webp new file mode 100644 index 0000000000..72eeb104bd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-48.webp new file mode 100644 index 0000000000..1024320d95 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-64.webp new file mode 100644 index 0000000000..03466276eb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TF-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-16.webp new file mode 100644 index 0000000000..b6462ea27f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-24.webp new file mode 100644 index 0000000000..2c6a0a91e0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-32.webp new file mode 100644 index 0000000000..b8bfe378f3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-48.webp new file mode 100644 index 0000000000..a18bfef407 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-64.webp new file mode 100644 index 0000000000..7b19b354d2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-16.webp new file mode 100644 index 0000000000..ed7a4a5454 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-24.webp new file mode 100644 index 0000000000..6d864c3ac0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-32.webp new file mode 100644 index 0000000000..cae61613c6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-48.webp new file mode 100644 index 0000000000..f14cc93838 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-64.webp new file mode 100644 index 0000000000..226edab4c6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-16.webp new file mode 100644 index 0000000000..10eab76731 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-24.webp new file mode 100644 index 0000000000..aba28e8767 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-32.webp new file mode 100644 index 0000000000..83c0751d70 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-48.webp new file mode 100644 index 0000000000..53e5df6fe5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-64.webp new file mode 100644 index 0000000000..2c73201e06 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-16.webp new file mode 100644 index 0000000000..1baef69949 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-24.webp new file mode 100644 index 0000000000..1fed1400d7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-32.webp new file mode 100644 index 0000000000..a203e1e211 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-48.webp new file mode 100644 index 0000000000..8b57dc3cbc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-64.webp new file mode 100644 index 0000000000..1ea52295f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TH-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-16.webp new file mode 100644 index 0000000000..cd7339cbbc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-24.webp new file mode 100644 index 0000000000..c0ec0f3126 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-32.webp new file mode 100644 index 0000000000..db019788d5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-48.webp new file mode 100644 index 0000000000..545e35bd87 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-64.webp new file mode 100644 index 0000000000..38c4de8d1d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-16.webp new file mode 100644 index 0000000000..e2a3289412 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-24.webp new file mode 100644 index 0000000000..d661f5b9d3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-32.webp new file mode 100644 index 0000000000..7f80e12ee2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-48.webp new file mode 100644 index 0000000000..c7ebdd2f36 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-64.webp new file mode 100644 index 0000000000..86edb83d72 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TJ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-16.webp new file mode 100644 index 0000000000..cd626f0912 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-24.webp new file mode 100644 index 0000000000..ce54963589 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-32.webp new file mode 100644 index 0000000000..51678ebc4f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-48.webp new file mode 100644 index 0000000000..a9621f19b1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-64.webp new file mode 100644 index 0000000000..4501812cc4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-16.webp new file mode 100644 index 0000000000..44e4253770 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-24.webp new file mode 100644 index 0000000000..8e1da7f0b1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-32.webp new file mode 100644 index 0000000000..b3aad316f2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-48.webp new file mode 100644 index 0000000000..9a96577729 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-64.webp new file mode 100644 index 0000000000..903baf387a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TK-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-16.webp new file mode 100644 index 0000000000..205d0818ee Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-24.webp new file mode 100644 index 0000000000..b76fb49b8c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-32.webp new file mode 100644 index 0000000000..b654b492be Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-48.webp new file mode 100644 index 0000000000..1ceffcc2fe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-64.webp new file mode 100644 index 0000000000..9599c35823 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-16.webp new file mode 100644 index 0000000000..7b03b115d9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-24.webp new file mode 100644 index 0000000000..734a270a51 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-32.webp new file mode 100644 index 0000000000..79de82434d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-48.webp new file mode 100644 index 0000000000..35b813a301 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-64.webp new file mode 100644 index 0000000000..c9037bcec5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TL-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-16.webp new file mode 100644 index 0000000000..13af60e6a5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-24.webp new file mode 100644 index 0000000000..e8c8cfe5f2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-32.webp new file mode 100644 index 0000000000..109509b00c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-48.webp new file mode 100644 index 0000000000..d3f027de20 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-64.webp new file mode 100644 index 0000000000..d6860aa3f6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-16.webp new file mode 100644 index 0000000000..c2bb72fb1d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-24.webp new file mode 100644 index 0000000000..d515a0b44d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-32.webp new file mode 100644 index 0000000000..0293470cec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-48.webp new file mode 100644 index 0000000000..9f8234510c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-64.webp new file mode 100644 index 0000000000..5d3eefc3dd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-16.webp new file mode 100644 index 0000000000..c478f55173 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-24.webp new file mode 100644 index 0000000000..9262e67a97 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-32.webp new file mode 100644 index 0000000000..ab38d23bd2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-48.webp new file mode 100644 index 0000000000..f8c7812191 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-64.webp new file mode 100644 index 0000000000..2ec2f5aae0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-16.webp new file mode 100644 index 0000000000..4422e8e3d0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-24.webp new file mode 100644 index 0000000000..7f44b59321 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-32.webp new file mode 100644 index 0000000000..85d4de2d68 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-48.webp new file mode 100644 index 0000000000..e7df8a9b6f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-64.webp new file mode 100644 index 0000000000..1729d8ec89 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-16.webp new file mode 100644 index 0000000000..3c04658f72 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-24.webp new file mode 100644 index 0000000000..c0d684c8a6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-32.webp new file mode 100644 index 0000000000..2451d33747 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-48.webp new file mode 100644 index 0000000000..03c10c84e1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-64.webp new file mode 100644 index 0000000000..134fc59867 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-16.webp new file mode 100644 index 0000000000..39e09e2bc8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-24.webp new file mode 100644 index 0000000000..ee56b649fd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-32.webp new file mode 100644 index 0000000000..e38102920b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-48.webp new file mode 100644 index 0000000000..b68c20b86a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-64.webp new file mode 100644 index 0000000000..d9b2984f8e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TO-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-16.webp new file mode 100644 index 0000000000..5d9072567f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-24.webp new file mode 100644 index 0000000000..926ba7173e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-32.webp new file mode 100644 index 0000000000..60e1404d2d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-48.webp new file mode 100644 index 0000000000..7f89f27798 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-64.webp new file mode 100644 index 0000000000..f14306844e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-16.webp new file mode 100644 index 0000000000..99fd5a3fb0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-24.webp new file mode 100644 index 0000000000..2dc13d1d89 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-32.webp new file mode 100644 index 0000000000..103747e9c7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-48.webp new file mode 100644 index 0000000000..a16bb467d1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-64.webp new file mode 100644 index 0000000000..c49fa7a1d7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TR-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-16.webp new file mode 100644 index 0000000000..a15e92c9d5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-24.webp new file mode 100644 index 0000000000..7d2f8704de Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-32.webp new file mode 100644 index 0000000000..01234780f2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-48.webp new file mode 100644 index 0000000000..7a2e8eb052 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-64.webp new file mode 100644 index 0000000000..0f7b7cf1a8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-16.webp new file mode 100644 index 0000000000..19770a07ed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-24.webp new file mode 100644 index 0000000000..36c80f1b31 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-32.webp new file mode 100644 index 0000000000..426f9c1894 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-48.webp new file mode 100644 index 0000000000..b656adf6fd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-64.webp new file mode 100644 index 0000000000..0f52b37889 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-16.webp new file mode 100644 index 0000000000..2a7383eb90 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-24.webp new file mode 100644 index 0000000000..f87b6287d6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-32.webp new file mode 100644 index 0000000000..5f3b5b3252 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-48.webp new file mode 100644 index 0000000000..ca4387f128 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-64.webp new file mode 100644 index 0000000000..9a5502ba4e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-16.webp new file mode 100644 index 0000000000..a0c0986558 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-24.webp new file mode 100644 index 0000000000..2f4f8bae61 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-32.webp new file mode 100644 index 0000000000..5ad76721f5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-48.webp new file mode 100644 index 0000000000..96496118fb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-64.webp new file mode 100644 index 0000000000..b54fc8cb83 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TV-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-16.webp new file mode 100644 index 0000000000..6a87b43805 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-24.webp new file mode 100644 index 0000000000..cab07f59d3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-32.webp new file mode 100644 index 0000000000..ad590e4564 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-48.webp new file mode 100644 index 0000000000..8a08458f6c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-64.webp new file mode 100644 index 0000000000..9f85cc8422 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-16.webp new file mode 100644 index 0000000000..109ee11102 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-24.webp new file mode 100644 index 0000000000..f4f56b288a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-32.webp new file mode 100644 index 0000000000..6a854b0860 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-48.webp new file mode 100644 index 0000000000..77cec673ab Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-64.webp new file mode 100644 index 0000000000..3d308f1aaf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-16.webp new file mode 100644 index 0000000000..4d70b1152f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-24.webp new file mode 100644 index 0000000000..9bcce79ec2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-32.webp new file mode 100644 index 0000000000..e6de742015 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-48.webp new file mode 100644 index 0000000000..9be186f1d6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-64.webp new file mode 100644 index 0000000000..0098445bf9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-16.webp new file mode 100644 index 0000000000..05daf3a283 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-24.webp new file mode 100644 index 0000000000..79542966db Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-32.webp new file mode 100644 index 0000000000..f5e5009b40 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-48.webp new file mode 100644 index 0000000000..016fcacd26 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-64.webp new file mode 100644 index 0000000000..e9560615db Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/TZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-16.webp new file mode 100644 index 0000000000..07aabe8419 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-24.webp new file mode 100644 index 0000000000..02634216ec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-32.webp new file mode 100644 index 0000000000..fc5fb6425d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-48.webp new file mode 100644 index 0000000000..bae4b836da Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-64.webp new file mode 100644 index 0000000000..5fdc9cff43 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-16.webp new file mode 100644 index 0000000000..936c49a7c4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-24.webp new file mode 100644 index 0000000000..7bb0c1b397 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-32.webp new file mode 100644 index 0000000000..afab247281 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-48.webp new file mode 100644 index 0000000000..ab06f0f763 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-64.webp new file mode 100644 index 0000000000..1b4e9cc20f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-16.webp new file mode 100644 index 0000000000..92b2018e1a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-24.webp new file mode 100644 index 0000000000..7f5a6ad3f8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-32.webp new file mode 100644 index 0000000000..f56b52a701 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-48.webp new file mode 100644 index 0000000000..f260299306 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-64.webp new file mode 100644 index 0000000000..617a8cc041 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-16.webp new file mode 100644 index 0000000000..3e68ecaeb0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-24.webp new file mode 100644 index 0000000000..180804a9ac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-32.webp new file mode 100644 index 0000000000..212c77d49e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-48.webp new file mode 100644 index 0000000000..95d11fbeaf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-64.webp new file mode 100644 index 0000000000..7ffcb3ea4f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-16.webp new file mode 100644 index 0000000000..828ec6901d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-24.webp new file mode 100644 index 0000000000..8957a722a3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-32.webp new file mode 100644 index 0000000000..149b5fb2fb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-48.webp new file mode 100644 index 0000000000..b6566ebc41 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-64.webp new file mode 100644 index 0000000000..6912527377 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-16.webp new file mode 100644 index 0000000000..ef39bfa710 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-24.webp new file mode 100644 index 0000000000..e50055da08 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-32.webp new file mode 100644 index 0000000000..39aaf442d4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-48.webp new file mode 100644 index 0000000000..6d4d392877 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-64.webp new file mode 100644 index 0000000000..970bc82a74 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/US-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-16.webp new file mode 100644 index 0000000000..d785baa1b9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-24.webp new file mode 100644 index 0000000000..1a8a3b3034 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-32.webp new file mode 100644 index 0000000000..7166d05edc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-48.webp new file mode 100644 index 0000000000..7926db2689 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-64.webp new file mode 100644 index 0000000000..a5d0d30247 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-16.webp new file mode 100644 index 0000000000..355e7c4ae7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-24.webp new file mode 100644 index 0000000000..9608a2b5c8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-32.webp new file mode 100644 index 0000000000..3657238c15 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-48.webp new file mode 100644 index 0000000000..369a9becac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-64.webp new file mode 100644 index 0000000000..187c79dac9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UY-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-16.webp new file mode 100644 index 0000000000..51d0e3c913 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-24.webp new file mode 100644 index 0000000000..272cab89ce Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-32.webp new file mode 100644 index 0000000000..cd992de84a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-48.webp new file mode 100644 index 0000000000..ce7ec795b0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-64.webp new file mode 100644 index 0000000000..0b499354f7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-16.webp new file mode 100644 index 0000000000..8ec7c83c25 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-24.webp new file mode 100644 index 0000000000..46e3649f07 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-32.webp new file mode 100644 index 0000000000..850de60893 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-48.webp new file mode 100644 index 0000000000..5c95fad46e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-64.webp new file mode 100644 index 0000000000..36a235b740 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/UZ-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-16.webp new file mode 100644 index 0000000000..49ced12117 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-24.webp new file mode 100644 index 0000000000..6300ccf3ef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-32.webp new file mode 100644 index 0000000000..8e80e762f9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-48.webp new file mode 100644 index 0000000000..1be45d886e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-64.webp new file mode 100644 index 0000000000..6e892f63ec Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-16.webp new file mode 100644 index 0000000000..41b7c5c9ff Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-24.webp new file mode 100644 index 0000000000..bd3e0eba87 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-32.webp new file mode 100644 index 0000000000..7b02ba8e55 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-48.webp new file mode 100644 index 0000000000..fa5b64bdcd Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-64.webp new file mode 100644 index 0000000000..27bcd98724 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-16.webp new file mode 100644 index 0000000000..d18a392b2c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-24.webp new file mode 100644 index 0000000000..3d8181b3ca Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-32.webp new file mode 100644 index 0000000000..90d63fa7fc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-48.webp new file mode 100644 index 0000000000..0ac94ce81c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-64.webp new file mode 100644 index 0000000000..4c630feb42 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-16.webp new file mode 100644 index 0000000000..b34f1e1b1a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-24.webp new file mode 100644 index 0000000000..e3eb4f599d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-32.webp new file mode 100644 index 0000000000..afa70b8967 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-48.webp new file mode 100644 index 0000000000..ee678fda3a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-64.webp new file mode 100644 index 0000000000..489cdf1bed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VC-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-16.webp new file mode 100644 index 0000000000..0d24c08b9c Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-24.webp new file mode 100644 index 0000000000..e481c675c1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-32.webp new file mode 100644 index 0000000000..64909ac994 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-48.webp new file mode 100644 index 0000000000..e27fcc97b7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-64.webp new file mode 100644 index 0000000000..78ced2f1a7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-16.webp new file mode 100644 index 0000000000..87c615ee7b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-24.webp new file mode 100644 index 0000000000..5ed2a64ba8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-32.webp new file mode 100644 index 0000000000..7951e317af Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-48.webp new file mode 100644 index 0000000000..9a2d3100a0 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-64.webp new file mode 100644 index 0000000000..f7b0c0c256 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-16.webp new file mode 100644 index 0000000000..f99faa6cad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-24.webp new file mode 100644 index 0000000000..efd3a10638 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-32.webp new file mode 100644 index 0000000000..c3b9f35424 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-48.webp new file mode 100644 index 0000000000..7342de4c15 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-64.webp new file mode 100644 index 0000000000..7dd2b67a23 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-16.webp new file mode 100644 index 0000000000..541ecb2ddc Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-24.webp new file mode 100644 index 0000000000..2ca318bf77 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-32.webp new file mode 100644 index 0000000000..5cc97804d8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-48.webp new file mode 100644 index 0000000000..b1ed05ba0a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-64.webp new file mode 100644 index 0000000000..3807d4a17b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VG-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-16.webp new file mode 100644 index 0000000000..4abdb4e67f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-24.webp new file mode 100644 index 0000000000..f682631a2d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-32.webp new file mode 100644 index 0000000000..f9bc2e6353 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-48.webp new file mode 100644 index 0000000000..bff2f2a9b9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-64.webp new file mode 100644 index 0000000000..2dfd5995be Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-16.webp new file mode 100644 index 0000000000..88de5e5009 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-24.webp new file mode 100644 index 0000000000..c0d6367408 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-32.webp new file mode 100644 index 0000000000..101854fc47 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-48.webp new file mode 100644 index 0000000000..f49d4f2b56 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-64.webp new file mode 100644 index 0000000000..23acd26ae9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VI-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-16.webp new file mode 100644 index 0000000000..0255cdb7f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-24.webp new file mode 100644 index 0000000000..e9f9f176ad Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-32.webp new file mode 100644 index 0000000000..57d59c8b20 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-48.webp new file mode 100644 index 0000000000..15c119286a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-64.webp new file mode 100644 index 0000000000..b1bfb5b1e7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-16.webp new file mode 100644 index 0000000000..e4c3d69993 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-24.webp new file mode 100644 index 0000000000..1a9e991942 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-32.webp new file mode 100644 index 0000000000..62d0c4a5c4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-48.webp new file mode 100644 index 0000000000..11e92cda75 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-64.webp new file mode 100644 index 0000000000..528e4d5ea9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VN-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-16.webp new file mode 100644 index 0000000000..ab2ac9eb6b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-24.webp new file mode 100644 index 0000000000..b63538590a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-32.webp new file mode 100644 index 0000000000..2c2f13e175 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-48.webp new file mode 100644 index 0000000000..2114241030 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-64.webp new file mode 100644 index 0000000000..5ccf8a05c2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-16.webp new file mode 100644 index 0000000000..ffdf8dc45e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-24.webp new file mode 100644 index 0000000000..a639e0699e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-32.webp new file mode 100644 index 0000000000..beeb85e397 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-48.webp new file mode 100644 index 0000000000..45efbb9205 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-64.webp new file mode 100644 index 0000000000..760b599709 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/VU-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-16.webp new file mode 100644 index 0000000000..c5cb2eb762 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-24.webp new file mode 100644 index 0000000000..b98b805bc9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-32.webp new file mode 100644 index 0000000000..35e77cfddf Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-48.webp new file mode 100644 index 0000000000..e606cc02da Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-64.webp new file mode 100644 index 0000000000..5eb1b5a398 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-16.webp new file mode 100644 index 0000000000..e591aeb7e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-24.webp new file mode 100644 index 0000000000..8f9ec09cee Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-32.webp new file mode 100644 index 0000000000..b14526c10a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-48.webp new file mode 100644 index 0000000000..4644911ca6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-64.webp new file mode 100644 index 0000000000..34fbf5e301 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WF-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-16.webp new file mode 100644 index 0000000000..fa872503d5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-24.webp new file mode 100644 index 0000000000..26b77569f8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-32.webp new file mode 100644 index 0000000000..afd3ebc444 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-48.webp new file mode 100644 index 0000000000..ae75ce85d8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-64.webp new file mode 100644 index 0000000000..dbc2bcafed Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-16.webp new file mode 100644 index 0000000000..67b9c550c8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-24.webp new file mode 100644 index 0000000000..330dee9678 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-32.webp new file mode 100644 index 0000000000..df8fcedd4b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-48.webp new file mode 100644 index 0000000000..ecabbd584d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-64.webp new file mode 100644 index 0000000000..ba64ed5415 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/WS-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-16.webp new file mode 100644 index 0000000000..bf7f35ea13 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-24.webp new file mode 100644 index 0000000000..5811168a07 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-32.webp new file mode 100644 index 0000000000..7223580f54 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-48.webp new file mode 100644 index 0000000000..1d02c18de3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-64.webp new file mode 100644 index 0000000000..ce3a96f3ac Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-16.webp new file mode 100644 index 0000000000..ff6f052e7f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-24.webp new file mode 100644 index 0000000000..c314be2cbe Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-32.webp new file mode 100644 index 0000000000..941faa3a3a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-48.webp new file mode 100644 index 0000000000..0b6c540a9f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-64.webp new file mode 100644 index 0000000000..07e5307254 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YE-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-16.webp new file mode 100644 index 0000000000..633ca851e5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-24.webp new file mode 100644 index 0000000000..aa8489d177 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-32.webp new file mode 100644 index 0000000000..b19979a517 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-48.webp new file mode 100644 index 0000000000..6262fb8405 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-64.webp new file mode 100644 index 0000000000..d1cc94a731 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-16.webp new file mode 100644 index 0000000000..f17aec386a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-24.webp new file mode 100644 index 0000000000..ecdff9fca4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-32.webp new file mode 100644 index 0000000000..7e1d784c34 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-48.webp new file mode 100644 index 0000000000..264bbec648 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-64.webp new file mode 100644 index 0000000000..6a46692246 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/YT-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-16.webp new file mode 100644 index 0000000000..5d9a56f3d2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-24.webp new file mode 100644 index 0000000000..2877bd97ea Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-32.webp new file mode 100644 index 0000000000..7aa0129bef Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-48.webp new file mode 100644 index 0000000000..f44985bc9a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-64.webp new file mode 100644 index 0000000000..b09552320f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-16.webp new file mode 100644 index 0000000000..1ccb0fced5 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-24.webp new file mode 100644 index 0000000000..0f9bfecdd3 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-32.webp new file mode 100644 index 0000000000..84351b70a6 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-48.webp new file mode 100644 index 0000000000..d78f1848c8 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-64.webp new file mode 100644 index 0000000000..77bdbb3af9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZA-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-16.webp new file mode 100644 index 0000000000..3e51f534e4 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-24.webp new file mode 100644 index 0000000000..27a6bade4b Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-32.webp new file mode 100644 index 0000000000..72d79a1b6f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-48.webp new file mode 100644 index 0000000000..5abf0310cb Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-64.webp new file mode 100644 index 0000000000..cf690fd40d Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-16.webp new file mode 100644 index 0000000000..82c4c5435f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-24.webp new file mode 100644 index 0000000000..d1053c4996 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-32.webp new file mode 100644 index 0000000000..e35d56b15e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-48.webp new file mode 100644 index 0000000000..a2af0afd82 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-64.webp new file mode 100644 index 0000000000..5ff9b4db6f Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZM-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-16.webp new file mode 100644 index 0000000000..f0256e18c7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-24.webp new file mode 100644 index 0000000000..908753fce9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-32.webp new file mode 100644 index 0000000000..eed9c50d3e Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-48.webp new file mode 100644 index 0000000000..f1f5b5642a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-64.webp new file mode 100644 index 0000000000..e0796823f7 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-flat-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-16.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-16.webp new file mode 100644 index 0000000000..8ce21907f2 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-16.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-24.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-24.webp new file mode 100644 index 0000000000..69987fb350 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-24.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-32.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-32.webp new file mode 100644 index 0000000000..c490b5bdf9 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-32.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-48.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-48.webp new file mode 100644 index 0000000000..97b45712f1 Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-48.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-64.webp b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-64.webp new file mode 100644 index 0000000000..0a93f44c6a Binary files /dev/null and b/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/flags/ZW-shiny-64.webp differ diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor index b5c2a67bd4..c326daa869 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor @@ -2,14 +2,19 @@ @inherits BitComponentBase @typeparam TItem -
+ dir="@Dir?.ToString().ToLower()" + aria-label="@AriaLabel"> @if (ChildContent is not null || Options is not null) { + @* The options report the order they are rendered in from here on, which is their markup order. *@ + @{ BeginOptionsOrder(); } @(Options ?? ChildContent) } @@ -20,4 +25,9 @@ <_BitAccordionListItem @key="@GetItemKey(item)" AccordionList="this" Item="item" /> } } + + @if (_ShowEmptyContent) + { + @EmptyContent + }
diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs index 76be31699a..7d9de72372 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs @@ -1,3 +1,6 @@ +using System.Globalization; +using System.Runtime.CompilerServices; + namespace Bit.BlazorUI; /// @@ -7,17 +10,54 @@ namespace Bit.BlazorUI; /// public partial class BitAccordionList : BitComponentBase where TItem : class { + // The keys the header of an item answers on top of the Tab key. They are suppressed on a listener of + // the browser's own, since Blazor's preventDefault directive cannot be decided per key, and a header + // that moves the focus while the page scrolls under it moves the reader twice. + private static readonly string[] _navigationKeys = ["ArrowDown", "ArrowUp", "Home", "End"]; + private int _optionKeySeed; + private bool _isToggling; + private bool _oldMultiple; + private bool _hasRendered; + private bool _pendingBoundKeysPush; + private bool _preventKeysRegistered; + private bool _collectingOptionOrder; + // Set by an option that registers after the first render: it is the only way _items can end up in an + // order other than the markup one, and what says the rendered document is worth reading back. + private bool _optionOrderIsStale; + private string? _togglingKey; private List _items = []; - private IEnumerable _oldItems = default!; + private List? _oldItems; private string? _internalExpandedKey; private List _internalExpandedKeys = []; - private readonly HashSet _expandedKeys = []; + private BitAccordionListClassStyles? _oldClasses; + private BitAccordionListClassStyles? _oldStyles; + private readonly List _optionOrder = []; + // The keys of the panels waiting to be scrolled into view. Keys rather than items, since a panel can be + // opened by the very change that mounts the item it belongs to - and that item is not there to name yet. + private readonly List _pendingScrolls = []; + private readonly HashSet _expandedKeys = new(StringComparer.Ordinal); + // The order the keys were expanded in, which is what MaxExpanded closes the oldest panel by. It is kept + // beside the set rather than in it, since a HashSet has no order of its own. + private readonly List _expandOrder = []; + private readonly Dictionary _fallbackKeys = new(ReferenceComparer.Instance); + private readonly Dictionary> _itemRefs = new(ReferenceComparer.Instance); internal BitAccordionClassStyles? _itemClasses; internal BitAccordionClassStyles? _itemStyles; + [Inject] private IJSRuntime _js { get; set; } = default!; + + + + /// + /// The custom template to render beside the header of each item, outside of the toggle button and of the + /// heading it sits in, so that it can hold its own interactive elements (a menu, a delete button, a switch). + /// Used when an item does not provide its own actions. + /// + [Parameter] public RenderFragment? ActionsTemplate { get; set; } + /// /// The color kind of the background of all the accordion items. /// @@ -38,6 +78,23 @@ public partial class BitAccordionList : BitComponentBase where TItem : cl /// [Parameter] public BitAccordionListClassStyles? Classes { get; set; } + /// + /// Allows the expanded item to be collapsed again from its own header. + ///
+ /// The default value is true. + ///
+ /// + /// Setting it to false keeps one item open at all times: the header of the last expanded item reports + /// itself as aria-disabled, the way the WAI-ARIA authoring practices ask a header that cannot + /// collapse its panel to, and no longer answers the pointer or the keyboard. + ///
+ /// It is the header that is closed off, not the list itself: the , + /// and methods still drive the AccordionList, and + /// nothing is expanded on its behalf, so a list that starts with everything collapsed stays that way until + /// something is opened. + ///
+ [Parameter] public bool Collapsible { get; set; } = true; + /// /// The custom template to render the body (content) of each item. Used when an item does not provide its own body. /// @@ -63,6 +120,22 @@ public partial class BitAccordionList : BitComponentBase where TItem : cl /// [Parameter, TwoWayBound] public IEnumerable? ExpandedKeys { get; set; } + /// + /// Gets or sets the icon to show in place of the expander icon of all items while they are expanded, using + /// custom CSS classes for external icon libraries. + /// Takes precedence over when both are set. + /// Setting either of them also turns the rotation of the expander icon off, since a swapped icon already + /// reports the state on its own. Can be overridden per item. + /// + [Parameter] public BitIconInfo? ExpandedExpanderIcon { get; set; } + + /// + /// Gets or sets the name of the icon, from the built-in Fluent UI icons, to show in place of the expander + /// icon of all items while they are expanded. + /// Setting it also turns the rotation of the expander icon off. Can be overridden per item. + /// + [Parameter] public string? ExpandedExpanderIconName { get; set; } + /// /// Gets or sets the icon to display as the expander of all items using custom CSS classes for external icon libraries. /// Takes precedence over when both are set. @@ -76,6 +149,40 @@ public partial class BitAccordionList : BitComponentBase where TItem : cl /// [Parameter] public string? ExpanderIconName { get; set; } + /// + /// Gets or sets the side of the header the expander icon of all the items sits on. + ///
+ /// The default value is . + ///
+ [Parameter] public BitIconPosition? ExpanderIconPosition { get; set; } + + /// + /// The custom template to render in place of the expander icon of each item, leaving the rest of the header + /// as it is. Used when an item does not provide its own expander template. + /// + [Parameter] public RenderFragment? ExpanderTemplate { get; set; } + + /// + /// Opens the panel of every item while the page is being printed, so that a collapsed section is not left + /// out of the paper as a bare header. + /// + /// + /// Content that is not in the DOM at all cannot be printed by any of this: a + /// panel that has never been opened, and every collapsed panel of a list that uses + /// , are still printed as a bare header. + /// + [Parameter] public bool ExpandOnPrint { get; set; } + + /// + /// The custom content to render in place of the items when the list has none. + /// + /// + /// A list built from or only knows it is empty once its + /// options have had their turn to register, so the empty content of one takes the render after the first + /// rather than the first itself; a list built from shows it right away. + /// + [Parameter] public RenderFragment? EmptyContent { get; set; } + /// /// The space (gap) in pixels between the accordion items. /// @@ -86,21 +193,100 @@ public partial class BitAccordionList : BitComponentBase where TItem : cl /// [Parameter] public RenderFragment? HeaderTemplate { get; set; } + /// + /// Gets or sets the heading level (aria-level) reported for the header of every item, so that the list + /// takes its right place in the heading outline of the page. + ///
+ /// The default value is 3, and the value is clamped to the 1..6 range. + ///
+ [Parameter] public int? HeadingLevel { get; set; } + + /// + /// Removes the expander icon from the header of all the items. Can be overridden per item. + /// + [Parameter] public bool HideExpanderIcon { get; set; } + /// /// The collection of items to render in the AccordionList. /// [Parameter] public IEnumerable Items { get; set; } = []; + /// + /// Delays the first render of the content of each item until it is expanded for the first time. The content + /// stays in the DOM afterwards, so the state it holds survives a collapse. + /// + [Parameter] public bool LazyContent { get; set; } + + /// + /// Gets or sets the maximum height of the content of every item (any CSS length), beyond which the content + /// scrolls inside the item instead of growing it. + /// + [Parameter] public string? MaxHeight { get; set; } + + /// + /// Gets or sets the greatest number of items that can be expanded at the same time in multiple-expand + /// mode. Expanding one more closes the panel that has been open the longest. + /// + /// + /// Nothing is turned away: a click always opens the panel it was aimed at, which is what tells this apart + /// from a limit that leaves a header answering nothing. A value below 1 is no limit at all, and the cap + /// applies to and to the default and the bound keys as well - the ones beyond it + /// are the ones dropped. It means nothing outside of , where one panel is the limit + /// already. + /// + [Parameter] public int? MaxExpanded { get; set; } + /// /// Enables the multiple-expand mode in which more than one item can be expanded at the same time. + /// caps how many of them may be. /// [Parameter, ResetClassBuilder] public bool Multiple { get; set; } + /// + /// Moves the focus between the headers of the items with the ArrowUp, ArrowDown, Home and End keys, which + /// the WAI-ARIA authoring practices offer as an addition to the Tab key rather than in place of it. + ///
+ /// The default value is true. + ///
+ /// + /// Only the headers answer these keys: the same keys pressed inside the panel of an item belong to whatever + /// the panel holds and are left alone. The navigation wraps around at both ends of the list and skips the + /// items that are disabled. + /// + [Parameter] public bool Navigable { get; set; } = true; + /// /// Removes the default border of all the accordion items and gives a background color to their body. /// [Parameter] public bool NoBorder { get; set; } + /// + /// Removes the region role from the panel of every item, leaving it a plain container. + /// + /// + /// The role names the panel as a landmark, which helps a screen reader user find their way back to the + /// content of a panel that holds headings or another accordion. The WAI-ARIA authoring practices ask for it + /// to be dropped where it would flood the page with landmarks instead - more than about six panels that can + /// all be open at the same time - which is what this is for. + /// + [Parameter] public bool NoContentRegion { get; set; } + + /// + /// Keeps the expander icon of every item still instead of turning it over when the item is expanded. + /// + [Parameter] public bool NoExpanderRotation { get; set; } + + /// + /// Stops the keyboard navigation of at the two ends of the list instead of + /// wrapping it around from the last header to the first and back. + /// + /// + /// The two are the linear and the circular navigation other libraries offer: wrapping + /// keeps the arrow keys moving forever, while stopping tells the reader where the list ends. The Home + /// and End keys still reach both ends either way. + /// + [Parameter] public bool NoNavigationLoop { get; set; } + /// /// The callback that is called when an item is collapsed. /// @@ -121,6 +307,22 @@ public partial class BitAccordionList : BitComponentBase where TItem : cl /// [Parameter] public EventCallback OnToggle { get; set; } + /// + /// Callback invoked before an item expands or collapses, letting the change be cancelled. + /// + /// + /// Set Cancel on the provided to leave the item as it + /// is, and read its Item, Key, IsExpanding and Reason to tell an expansion from a + /// collapse and a click on a header from an , , + /// , or call. Since the callback + /// is awaited, it can also run asynchronous work first, and nothing else toggles the list while it is running. + ///
+ /// The implicit collapse of the previously expanded item in single-expand mode is part of the expansion that + /// caused it and is not offered here; it is still reported through and + /// . + ///
+ [Parameter] public EventCallback> OnToggling { get; set; } + /// /// Alias of the ChildContent. /// @@ -131,55 +333,194 @@ public partial class BitAccordionList : BitComponentBase where TItem : cl /// [Parameter] public BitAccordionListNameSelectors? NameSelectors { get; set; } + /// + /// Leaves every item where it is: the headers keep their colors and their place in the tab order, but they + /// no longer answer the pointer or the keyboard. Can be overridden per item. + /// + /// + /// This is the list whose panels have to stay as they are rather than the one that is turned off, so the + /// headers report themselves as aria-disabled without being greyed out the way + /// greys them. still reports the click, + /// and the public methods still drive the list. + /// + [Parameter] public bool ReadOnly { get; set; } + + /// + /// Brings the item that has just been expanded into view, so that a panel opened at the bottom of the + /// window is not left off the screen it was opened on. + /// + /// + /// The item is moved as little as the browser can move it, so nothing happens to one that is already in + /// view, and the scroll is instant rather than smooth for a reader who has asked for less motion. It + /// covers the ways a single panel opens - a click on its header, , + /// and the bound keys - and runs when the panel is put on screen rather than + /// when the transition that opens it ends. scrolls to nothing: there is no one + /// panel it opened. + /// + [Parameter] public bool ScrollIntoViewOnExpand { get; set; } + + /// + /// Gets or sets the size of all the accordion items, which drives the padding of the headers and of the + /// contents and the size of the titles. + ///
+ /// The default value is . + ///
+ [Parameter] public BitSize? Size { get; set; } + /// /// Custom CSS styles for different parts of the AccordionList. /// [Parameter] public BitAccordionListClassStyles? Styles { get; set; } + /// + /// The custom template to render in place of the title of each item, leaving the rest of the header as it is. + /// Used when an item does not provide its own title template. + /// + [Parameter] public RenderFragment? TitleTemplate { get; set; } + + /// + /// Gets or sets the duration of the expand/collapse transition of every item in milliseconds, overriding the + /// duration the theme provides. A reduced-motion preference still collapses it, unless the ForceAnimation + /// parameter opts out of that. + /// + [Parameter] public int? TransitionDuration { get; set; } + + /// + /// Removes the content of an item from the DOM while it is collapsed, so that nothing it holds keeps running + /// behind a closed header. + /// + [Parameter] public bool UnmountOnCollapse { get; set; } + /// - /// Expands all the items (only effective in multiple-expand mode). + /// Expands all the items (only effective in multiple-expand mode). Disabled items are left as they are, + /// since their headers could not close again what would be opened for them. /// public async Task ExpandAll() { if (Multiple is false) return; - foreach (var item in _items) + var changed = false; + + foreach (var item in _items.ToArray()) { + if (GetIsEnabled(item) is false) continue; + + // The cap is a cap on the whole list, so ExpandAll stops at it rather than opening every panel + // and letting each one close the one before it. + if (_MaxExpanded is int max && _expandedKeys.Count >= max) break; + var key = GetItemKey(item); if (key.HasNoValue() || _expandedKeys.Contains(key!)) continue; - _expandedKeys.Add(key!); - SetIsExpanded(item, true); - await OnExpand.InvokeAsync(item); - await OnToggle.InvokeAsync(item); + changed |= await ApplyToggle(item, key!, true, BitAccordionToggleReason.Method); } + if (changed is false) return; + await UpdateBoundKeys(); - RefreshOptions(); - StateHasChanged(); + await RefreshAndRender(); } /// - /// Collapses all the expanded items. + /// Collapses all the expanded items, the disabled ones included. /// + /// + /// Unlike , which cannot open what is turned off, this one closes every panel: a + /// disabled item whose panel was opened by a default value would otherwise be left open with no way of + /// closing it, since its own header answers nothing. + /// public async Task CollapseAll() { - foreach (var item in _items) + var changed = false; + + foreach (var item in _items.ToArray()) { var key = GetItemKey(item); if (key.HasNoValue() || _expandedKeys.Contains(key!) is false) continue; - _expandedKeys.Remove(key!); - SetIsExpanded(item, false); - await OnCollapse.InvokeAsync(item); - await OnToggle.InvokeAsync(item); + changed |= await ApplyToggle(item, key!, false, BitAccordionToggleReason.Method); + } + + // Keys that no longer map to an item of the list are dropped along with the rest, so a collapsed list + // does not keep reporting them through the two-way bound ExpandedKey(s). + var orphans = _expandedKeys.Where(k => FindItem(k) is null).ToArray(); + if (orphans.Length > 0) + { + foreach (var orphan in orphans) RemoveExpandedKey(orphan); + changed = true; } + if (changed is false) return; + await UpdateBoundKeys(); - RefreshOptions(); - StateHasChanged(); + await RefreshAndRender(); + } + + /// + /// Expands the item with the provided key. Does nothing if it is already expanded or if no item carries + /// that key. In single-expand mode the currently expanded item is collapsed along the way. + /// + /// + /// A call of its own is not turned away by , by + /// or by : what those close off is the way in from the + /// header, not the one the app itself uses. + /// + public Task Expand(string key) => SetExpandedByKey(key, true); + + /// + /// Collapses the item with the provided key. Does nothing if it is already collapsed or if no item carries + /// that key. + /// + /// + /// Not turned away by , or + /// ; see . + /// + public Task Collapse(string key) => SetExpandedByKey(key, false); + + /// + /// Expands the item with the provided key if it is collapsed and collapses it if it is expanded. + /// + /// + /// Not turned away by , or + /// ; see . + /// + public Task Toggle(string key) + { + return key.HasNoValue() ? Task.CompletedTask : SetExpandedByKey(key, _expandedKeys.Contains(key) is false); + } + + /// + /// Reports whether the item with the provided key is currently expanded. + /// + public bool IsExpanded(string? key) => key.HasValue() && _expandedKeys.Contains(key!); + + /// + /// Returns the keys of the currently expanded items, in the order of the items of the list. + /// + public IReadOnlyList GetExpandedKeys() => GetOrderedExpandedKeys(); + + /// + /// Gives the focus to the header of the item with the provided key. + /// + public async Task FocusItem(string key) + { + var item = FindItem(key); + if (item is null) return; + + await InvokeAsync(() => FocusItemCore(item)); + } + + /// + /// Gives the focus to the header of the first item of the list that can take it. + /// + public async Task FocusAsync() + { + var item = _items.FirstOrDefault(GetIsEnabled); + if (item is null) return; + + await InvokeAsync(() => FocusItemCore(item)); } @@ -190,10 +531,10 @@ internal void RegisterOption(BitAccordionListOption option) { // Use a monotonic seed so keys remain unique even after removals, and guard // against colliding with any existing explicit keys. - var key = (_optionKeySeed++).ToString(); + var key = _optionKeySeed++.ToString(CultureInfo.InvariantCulture); while (_items.Any(i => GetItemKey(i) == key)) { - key = (_optionKeySeed++).ToString(); + key = _optionKeySeed++.ToString(CultureInfo.InvariantCulture); } option.Key = key; } @@ -202,11 +543,22 @@ internal void RegisterOption(BitAccordionListOption option) _items.Add(item); - if (ShouldExpandOnRegister(option.Key!, option.IsExpanded)) + // An option that arrives after the first render is one the markup added conditionally, so it lands + // behind every option that was already there wherever in the markup it sits. + if (_hasRendered) _optionOrderIsStale = true; + + // An option opening itself on registration is held to MaxExpanded like a set of defaults is: the ones + // registering after the cap is reached stay closed rather than pushing the list beyond it. + if (ShouldExpandOnRegister(option.Key!, option.IsExpanded) && (_MaxExpanded is not int max || _expandedKeys.Count < max)) { - _expandedKeys.Add(option.Key!); + AddExpandedKey(option.Key!); _internalExpandedKeys = GetOrderedExpandedKeys(); _internalExpandedKey = _internalExpandedKeys.FirstOrDefault(); + + // The bound value is pushed as well, so a page that binds ExpandedKey(s) is told about the option + // that opened itself on registration rather than being left with a stale value. It is deferred to + // the end of the render, since the registration runs in the middle of one. + _pendingBoundKeysPush = true; } StateHasChanged(); @@ -247,12 +599,16 @@ private bool ShouldExpandOnRegister(string key, bool optionIsExpanded) internal async Task UnregisterOption(BitAccordionListOption option) { - _items.Remove((option as TItem)!); + var item = (option as TItem)!; + + _items.Remove(item); + _itemRefs.Remove(item); + _fallbackKeys.Remove(item); var wasExpanded = false; if (option.Key.HasValue()) { - wasExpanded = _expandedKeys.Remove(option.Key!); + wasExpanded = RemoveExpandedKey(option.Key!); } // When a removed option was expanded, refresh the internal representations and the @@ -265,6 +621,50 @@ internal async Task UnregisterOption(BitAccordionListOption option) StateHasChanged(); } + // An option registers itself when it is initialized, which is the markup order only for the options that + // were there on the first render: one added conditionally later registers behind every option that was + // already there, wherever in the markup it sits. So the order is read back from the render itself - the + // options render in markup order - and _items is put back into it once the render is over. It is what the + // keyboard navigation walks and what the expanded keys are reported in, so it has to be the order the + // reader sees rather than the order the options happened to arrive in. + internal void BeginOptionsOrder() + { + // A pass that is already open is left as it is: registering an option asks the list to render again, + // and that second render lands in the same batch as the first - so clearing here would throw away + // the very order the options had just reported. + if (_collectingOptionOrder) return; + + _optionOrder.Clear(); + _collectingOptionOrder = true; + } + + internal void ReportOptionOrder(BitAccordionListOption option) + { + if (_collectingOptionOrder is false) return; + + var item = (option as TItem)!; + + if (_optionOrder.Any(i => ReferenceEquals(i, item))) return; + + _optionOrder.Add(item); + } + + internal void RegisterItem(TItem item, _BitAccordionListItem itemRef) + { + _itemRefs[item] = itemRef; + + // The panel of an item that is only being mounted now can already be waiting to be scrolled into + // view, and nothing else would ask for the render that brings it there: registering an element is + // bookkeeping of the item's own and puts nothing new on screen. + var key = GetItemKey(item); + if (key.HasValue() && _pendingScrolls.Contains(key!, StringComparer.Ordinal)) StateHasChanged(); + } + + internal void UnregisterItem(TItem item) + { + _itemRefs.Remove(item); + } + protected override string RootElementClass => "bit-acl"; @@ -283,40 +683,68 @@ protected override void RegisterCssStyles() StyleBuilder.Register(() => Gap.HasValue ? $"gap:{Gap}px" : string.Empty); } - protected override async Task OnInitializedAsync() - { - _items = (ChildContent is null && Options is null && Items is not null) ? [.. Items] : []; - - if (ChildContent is null && Options is null) - { - AssignItemKeys(); - InitializeExpandedKeys(); - } - - await base.OnInitializedAsync(); - } - protected override async Task OnParametersSetAsync() { BuildItemClassStyles(); if (ChildContent is null && Options is null && Items is not null) { - if (_oldItems is null || (ReferenceEquals(Items, _oldItems) is false && Items.SequenceEqual(_oldItems) is false)) + // The snapshot is a copy rather than the collection itself, so a page that keeps mutating the very + // list it handed over - adding an item to it, removing one - is still noticed here. A lazy sequence + // is walked once, so what is compared is also exactly what is kept. + List snapshot = [.. Items]; + + if (_oldItems is null || snapshot.SequenceEqual(_oldItems) is false) { - _oldItems = Items; - _items = [.. Items]; + var isFirstPass = _oldItems is null; + + _oldItems = snapshot; + _items = [.. snapshot]; + AssignItemKeys(); - InitializeExpandedKeys(); + + // Only the very first pass falls back to the default values: a later change of the collection + // must not throw away the state the reader has built up by opening and closing the panels. + InitializeExpandedKeys(preserveCurrent: isFirstPass is false); } } + // Leaving the multiple-expand mode with more than one panel open would otherwise keep them all open + // until the next click, which is the one state a single-expand list is there to rule out. + if (_oldMultiple && Multiple is false && _expandedKeys.Count > 1) + { + var kept = GetOrderedExpandedKeys().FirstOrDefault(); + + ClearExpandedKeys(); + if (kept.HasValue()) AddExpandedKey(kept!); + + SyncItemsExpandedState(); + + _internalExpandedKeys = GetOrderedExpandedKeys(); + _internalExpandedKey = _internalExpandedKeys.FirstOrDefault(); + + // The push is deferred to the end of the render, since a parameter set is no place to call back + // into the page that is setting them. + _pendingBoundKeysPush = true; + } + + _oldMultiple = Multiple; + // React to external (controlled) changes of the bound keys. if (Multiple) { if (ExpandedKeysHasBeenSet && (ExpandedKeys ?? []).SequenceEqual(_internalExpandedKeys) is false) { SyncFromExpandedKeys(ExpandedKeys); + + // Not every set of keys survives the way in whole: the ones beyond MaxExpanded are dropped, + // and so are the empty and the repeated ones. The page is told what the list actually holds + // rather than being left with a value it does not show - and rather than being read again as + // a change on every render that follows. + if ((ExpandedKeys ?? []).SequenceEqual(_internalExpandedKeys) is false) + { + _pendingBoundKeysPush = true; + } } } else @@ -327,6 +755,26 @@ protected override async Task OnParametersSetAsync() } } + // A cap that arrives - or is lowered - while more panels are open than it allows closes the oldest of + // them, the same way opening one more would have. Everything that adds a key already stops at the cap, + // so this is only about the cap itself changing. + if (_MaxExpanded is int max && _expandedKeys.Count > max) + { + foreach (var key in _expandOrder.Take(_expandedKeys.Count - max).ToArray()) + { + RemoveExpandedKey(key); + } + + SyncItemsExpandedState(); + + _internalExpandedKeys = GetOrderedExpandedKeys(); + _internalExpandedKey = _internalExpandedKeys.FirstOrDefault(); + + // The push is deferred to the end of the render, since a parameter set is no place to call back + // into the page that is setting them. + _pendingBoundKeysPush = true; + } + // Options render their items themselves and Blazor skips re-rendering them when only the // accordion list's own parameters (Styles, ExpandedKey(s), ...) change, so push a re-render to each one. RefreshOptions(); @@ -334,18 +782,203 @@ protected override async Task OnParametersSetAsync() await base.OnParametersSetAsync(); } + protected override async Task OnAfterRenderAsync(bool firstRender) + { + // A list of options only knows it is empty once its options have had their turn to register, and the + // first render is where that is learned - so the empty content it was given needs a render of its own + // to appear in. Nothing else would ask for one: an empty list has no option to report anything. + var showEmptyContent = _ShowEmptyContent; + + _hasRendered = true; + + if (showEmptyContent is false && _ShowEmptyContent) + { + StateHasChanged(); + } + + await ReorderOptions(); + + if (_pendingBoundKeysPush) + { + _pendingBoundKeysPush = false; + + await PushBoundKeys(); + } + + await UpdatePreventedKeys(); + + await ScrollPendingItemsIntoView(); + + await base.OnAfterRenderAsync(firstRender); + } + + // Puts _items back into the order the options were rendered in, which is their markup order. + private async Task ReorderOptions() + { + if (_collectingOptionOrder is false) return; + + _collectingOptionOrder = false; + + // A pass in which not every option had its turn says nothing about the order of the ones that + // did, so it is thrown away rather than guessed at. Blazor hands a child its parameters again + // only when one of them has actually changed, so a list whose options carry nothing but + // constants - no content, no template, no handler - can render without any of them reporting. + var complete = _optionOrder.Count == _items.Count; + var order = complete ? _optionOrder.ToArray() : []; + + _optionOrder.Clear(); + + // What the options could not report is read back from the document they were rendered into, which + // holds the markup order whether they reported it or not. + if (complete is false) + { + order = await ReadOptionOrderFromDom(); + if (order.Length == 0) return; + } + else + { + _optionOrderIsStale = false; + } + + if (_items.SequenceEqual(order, ReferenceComparer.Instance)) return; + + _items = [.. order]; + + // Nothing on screen depends on the order - the options render their own items in place - but the + // keys the list reports do, so they are pushed again where the order changed them. + if (GetOrderedExpandedKeys().SequenceEqual(_internalExpandedKeys) is false) + { + await UpdateBoundKeys(); + } + + StateHasChanged(); + } + + // The order of this list's own items in the rendered document, which is the markup order of the options + // that rendered them. It is only asked for where an option was added after the first render - the one + // case _items can be out of order - and only where the options themselves could not report it. + private async Task ReadOptionOrderFromDom() + { + if (_optionOrderIsStale is false) return []; + + var items = _items.ToArray(); + var elements = new ElementReference[items.Length]; + + for (int i = 0; i < items.Length; i++) + { + // An item that has not registered its element yet is one this render has just mounted: its own + // OnAfterRender is still to come, so the reading is left to the render that follows this one. + if (_itemRefs.TryGetValue(items[i], out var itemRef) is false) return []; + + var element = itemRef.GetElement(); + if (element is null) return []; + + elements[i] = element.Value; + } + + int[]? indexes; + try + { + indexes = await _js.BitExtrasGetElementsOrder(elements); + } + catch (JSDisconnectedException) { return []; } // we can ignore this exception here + + // An element that is not in the document is left out of the answer, so a partial one is no order at + // all - the same way a partial pass of the options is none. Anything that is not a permutation of + // what was sent is not an order of these items either. + if (indexes is null || indexes.Length != items.Length) return []; + if (indexes.Distinct().Count() != items.Length) return []; + if (indexes.Any(i => i < 0 || i >= items.Length)) return []; + + _optionOrderIsStale = false; + + return [.. indexes.Select(i => items[i])]; + } + + // The navigation keys are suppressed on a listener of the browser's own, and only for a key pressed on + // one of this list's own item headers: the same keys pressed inside a panel belong to whatever the panel + // holds, and the ones pressed on the headers of a list nested in a panel belong to that list. The header + // is matched through the whole chain of an item's own accordion, since a plain BitAccordion placed in a + // panel or in the Actions carries the same header class but none of the navigation that would stand in + // for the default action the listener takes away. + private const string ItemHeaderSelector = ".bit-acl-itm > .bit-acd > .bit-acd-hwr > .bit-acd-hed > .bit-acd-hdr"; + + private async Task UpdatePreventedKeys() + { + var wanted = Navigable && IsEnabled; + + if (wanted == _preventKeysRegistered) return; + + try + { + if (wanted) + { + await _js.BitExtrasSetPreventKeys(RootElement, _navigationKeys, ItemHeaderSelector, ".bit-acl"); + } + else + { + await _js.BitExtrasDisposePreventKeys(RootElement); + } + + _preventKeysRegistered = wanted; + } + catch (JSDisconnectedException) { } // we can ignore this exception here + } + + private async Task ScrollPendingItemsIntoView() + { + if (_pendingScrolls.Count == 0) return; + + var keys = _pendingScrolls.ToArray(); + _pendingScrolls.Clear(); + + foreach (var key in keys) + { + var item = FindItem(key); + var element = (item is not null && _itemRefs.TryGetValue(item, out var itemRef)) ? itemRef.GetElement() : null; + + if (element is null) + { + // The item the panel belongs to can be one that is only being mounted by the change that + // opened it: it registers itself, and then its element, in renders that come after the one + // this is running at the end of. So the key waits here until it does - the registration asks + // for the render that scrolls it - and is dropped as soon as the panel it names is closed. + if (_expandedKeys.Contains(key)) _pendingScrolls.Add(key); + + continue; + } + + try + { + await _js.BitExtrasScrollIntoView(element.Value); + } + catch (JSDisconnectedException) { } // we can ignore this exception here + } + } + private void AssignItemKeys() { - // Collect the explicit keys first so the auto-generated keys never collide with them. - var usedKeys = new HashSet(); + // Collect the explicit keys first so the generated keys never collide with them. + var usedKeys = new HashSet(StringComparer.Ordinal); foreach (var item in _items) { - var key = GetItemKey(item); + var key = GetDeclaredKey(item); if (key.HasValue()) usedKeys.Add(key!); } + var present = new HashSet(_items, ReferenceComparer.Instance); + + foreach (var item in _fallbackKeys.Keys.ToArray()) + { + // A key handed out earlier is kept where the item is still in the list and the key is still free, + // so an item does not lose its expanded state only because the collection around it changed. + if (present.Contains(item) && usedKeys.Add(_fallbackKeys[item])) continue; + + _fallbackKeys.Remove(item); + } + for (int i = 0; i < _items.Count; i++) { var item = _items[i]; @@ -354,10 +987,10 @@ private void AssignItemKeys() // Start from the loop index and increment until a non-colliding key is found so the // result stays deterministic across renders while remaining unique. var suffix = i; - var candidate = suffix.ToString(); + var candidate = suffix.ToString(CultureInfo.InvariantCulture); while (usedKeys.Contains(candidate)) { - candidate = (++suffix).ToString(); + candidate = (++suffix).ToString(CultureInfo.InvariantCulture); } SetItemKey(item, candidate); @@ -365,48 +998,58 @@ private void AssignItemKeys() } } - private void InitializeExpandedKeys() + private void InitializeExpandedKeys(bool preserveCurrent = false) { - _expandedKeys.Clear(); + // Read before the set is cleared: the keys of the items that were expanded and are still in the list. + var surviving = preserveCurrent ? GetSurvivingExpandedKeys() : null; + var selfExpanded = GetSelfExpandedKeys(); + + ClearExpandedKeys(); - // Controlled values take precedence over default values. + // Controlled values take precedence over what was there before, which takes precedence over the + // default values, which take precedence over the items' own IsExpanded. if (Multiple) { if (ExpandedKeysHasBeenSet && ExpandedKeys is not null) { AddExpandedKeys(ExpandedKeys); } + else if (surviving is not null) + { + AddExpandedKeys(surviving); + AddExpandedKeys(selfExpanded); + } else if (DefaultExpandedKeys is not null) { AddExpandedKeys(DefaultExpandedKeys); } else { - foreach (var item in _items.Where(GetIsExpanded)) - { - var key = GetItemKey(item); - if (key.HasValue()) _expandedKeys.Add(key!); - } + AddExpandedKeys(selfExpanded); } } else { - string? key = null; + string? key; if (ExpandedKeyHasBeenSet) { key = ExpandedKey; } + else if (surviving is not null) + { + key = surviving.FirstOrDefault() ?? selfExpanded.FirstOrDefault(); + } else if (DefaultExpandedKey.HasValue()) { key = DefaultExpandedKey; } else { - key = _items.Where(GetIsExpanded).Select(GetItemKey).FirstOrDefault(k => k.HasValue()); + key = selfExpanded.FirstOrDefault(); } - if (key.HasValue()) _expandedKeys.Add(key!); + if (key.HasValue()) AddExpandedKey(key!); } SyncItemsExpandedState(); @@ -415,16 +1058,71 @@ private void InitializeExpandedKeys() _internalExpandedKey = _internalExpandedKeys.FirstOrDefault(); } + private List GetSurvivingExpandedKeys() + { + return [.. _items.Select(GetItemKey).Where(k => k.HasValue() && _expandedKeys.Contains(k!)).Select(k => k!)]; + } + + private List GetSelfExpandedKeys() + { + return [.. _items.Where(GetIsExpanded).Select(GetItemKey).Where(k => k.HasValue()).Select(k => k!)]; + } + private void AddExpandedKeys(IEnumerable keys) { foreach (var key in keys) { if (key.HasNoValue()) continue; - _expandedKeys.Add(key); + AddExpandedKey(key); if (Multiple is false) break; + + // The keys beyond the cap are the ones dropped, so a set of defaults or of bound keys longer + // than MaxExpanded opens the first of them rather than none of them. + if (_MaxExpanded is int max && _expandedKeys.Count >= max) break; } } + // The three of them are what keeps _expandOrder - the order the panels were opened in, which is what + // MaxExpanded closes the oldest one by - beside the set that answers whether a key is expanded at all. + private bool AddExpandedKey(string key) + { + if (_expandedKeys.Add(key) is false) return false; + + _expandOrder.Add(key); + + return true; + } + + private bool RemoveExpandedKey(string key) + { + if (_expandedKeys.Remove(key) is false) return false; + + _expandOrder.Remove(key); + + return true; + } + + private void ClearExpandedKeys() + { + _expandedKeys.Clear(); + _expandOrder.Clear(); + } + + // A cap of its own only means something where more than one panel can be open at a time, and a value + // below one is no cap at all rather than a list nothing can be opened in. + private int? _MaxExpanded => (Multiple && MaxExpanded is > 0) ? MaxExpanded : null; + + // The keys that have to close for the one being opened to fit under the cap, oldest first. + private string[] GetOverflowKeys(string key) + { + if (_MaxExpanded is not int max) return []; + + var overflow = _expandedKeys.Count + 1 - max; + if (overflow <= 0) return []; + + return [.. _expandOrder.Where(k => k != key).Take(overflow)]; + } + private void SyncItemsExpandedState() { foreach (var item in _items) @@ -439,7 +1137,7 @@ private void SyncItemsExpandedState() private List GetOrderedExpandedKeys() { var ordered = new List(_expandedKeys.Count); - var seen = new HashSet(); + var seen = new HashSet(StringComparer.Ordinal); foreach (var item in _items) { @@ -462,78 +1160,226 @@ private List GetOrderedExpandedKeys() private void SyncFromExpandedKey(string? key) { - _expandedKeys.Clear(); - if (key.HasValue()) _expandedKeys.Add(key!); + // Read before the set is replaced, so that a panel the page has just opened through the binding is + // brought into view the way a click on its header would have brought it. + var opened = OpenedKeysOf(key.HasValue() ? [key!] : []); + + ClearExpandedKeys(); + if (key.HasValue()) AddExpandedKey(key!); SyncItemsExpandedState(); _internalExpandedKey = key; + + QueueScrollIntoView(opened); } private void SyncFromExpandedKeys(IEnumerable? keys) { - _expandedKeys.Clear(); + var opened = OpenedKeysOf(keys ?? []); + + ClearExpandedKeys(); if (keys is not null) AddExpandedKeys(keys); SyncItemsExpandedState(); _internalExpandedKeys = GetOrderedExpandedKeys(); + + QueueScrollIntoView(opened); + } + + // The keys of the incoming set that are not expanded yet - the panels the change is about to open. + // Before the first render none is: the bound value is the state the list starts in, not a panel the + // reader has opened. A list of options has no item yet on its first parameter pass - they register + // during the render - so its bound keys would otherwise all read as just opened and scroll the page. + private List OpenedKeysOf(IEnumerable keys) + { + if (ScrollIntoViewOnExpand is false || _hasRendered is false) return []; + + return [.. keys.Where(k => k.HasValue() && _expandedKeys.Contains(k) is false)]; + } + + private void QueueScrollIntoView(IEnumerable keys) + { + foreach (var key in keys) + { + // Not every key of an incoming set opens a panel: the ones beyond MaxExpanded are dropped on the + // way in, and a panel that was never opened is nothing to scroll to. + if (_expandedKeys.Contains(key) is false) continue; + + QueueScrollIntoView(key); + } + } + + private void QueueScrollIntoView(TItem item) + { + var key = GetItemKey(item); + + if (key.HasValue()) QueueScrollIntoView(key!); + } + + // The scroll is left to the render that puts the panel on screen: the item it belongs to can be one + // that is only rendered - or only registered - by the change being applied here. + private void QueueScrollIntoView(string key) + { + if (ScrollIntoViewOnExpand is false) return; + + if (_pendingScrolls.Contains(key, StringComparer.Ordinal)) return; + + _pendingScrolls.Add(key); } internal async Task HandleOnItemClick(TItem item) { if (IsEnabled is false || GetIsEnabled(item) is false) return; - _ = OnItemClick.InvokeAsync(item); + await OnItemClick.InvokeAsync(item); - InvokeItemClick(item); + await InvokeItemClick(item); + + // A read-only item still reports the click - the page can want to say why the panel is staying where + // it is - it just does not act on it. + if (GetItemIsReadOnly(item)) return; var key = GetItemKey(item); if (key.HasNoValue()) return; - var isExpanded = _expandedKeys.Contains(key!); + var expand = _expandedKeys.Contains(key!) is false; - await ToggleItem(item, key!, isExpanded is false); + await ToggleItem(item, key!, expand, BitAccordionToggleReason.Click); } - private async Task ToggleItem(TItem item, string key, bool expand) + internal async Task HandleOnItemKeyDown(KeyboardEventArgs e, TItem item) { - if (expand) + if (Navigable is false || IsEnabled is false) return; + + if (e.Key is not ("ArrowDown" or "ArrowUp" or "Home" or "End")) return; + + // A disabled header is out of the tab order, so the navigation walks past it rather than parking the + // focus on something that cannot be reached by the Tab key either. + var focusables = _items.Where(GetIsEnabled).ToList(); + if (focusables.Count == 0) return; + + var index = focusables.FindIndex(i => ReferenceEquals(i, item)); + if (index < 0) return; + + var next = e.Key switch { - if (Multiple is false) + "ArrowDown" => index + 1, + "ArrowUp" => index - 1, + "Home" => 0, + _ => focusables.Count - 1 + }; + + // The navigation wraps around at both ends of the list, unless it was asked to stop there. + if (next < 0) next = NoNavigationLoop ? 0 : focusables.Count - 1; + else if (next >= focusables.Count) next = NoNavigationLoop ? focusables.Count - 1 : 0; + + await FocusItemCore(focusables[next]); + } + + private async Task SetExpandedByKey(string key, bool expand) + { + if (key.HasNoValue()) return; + + var item = FindItem(key); + if (item is null) return; + + if (_expandedKeys.Contains(key) == expand) return; + + await ToggleItem(item, key, expand, BitAccordionToggleReason.Method); + } + + private async Task ToggleItem(TItem item, string key, bool expand, BitAccordionToggleReason reason) + { + // Read before the expansion is applied, since applying it adds the new key to the set. A cancelled + // expansion therefore leaves the previously expanded item(s) exactly where they were. + // + // In single-expand mode that is every other panel; in multiple-expand mode under a MaxExpanded cap + // it is the oldest of them, as many as the one being opened needs to fit. + var others = expand + ? (Multiple ? GetOverflowKeys(key) : [.. _expandedKeys.Where(k => k != key)]) + : []; + + if (await ApplyToggle(item, key, expand, reason) is false) return; + + if (expand) QueueScrollIntoView(item); + + // Collapse the item(s) that were expanded before. + foreach (var otherKey in others) + { + if (RemoveExpandedKey(otherKey) is false) continue; + + var otherItem = FindItem(otherKey); + if (otherItem is null) continue; + + SetIsExpanded(otherItem, false); + await OnCollapse.InvokeAsync(otherItem); + await OnToggle.InvokeAsync(otherItem); + } + + await UpdateBoundKeys(); + + // A toggle can affect other items too (single-expand mode collapses the previously expanded + // item), and the click handler runs on the clicked item's renderer, so both the registered + // options and the accordion list itself need an explicit re-render. + await RefreshAndRender(); + } + + // Runs the cancellable OnToggling callback and, when it is not refused, moves the single item between the + // expanded and the collapsed state. The bound keys and the re-render are left to the caller, so that a + // batch of items - ExpandAll, CollapseAll - reports itself once rather than once per item. + private async Task ApplyToggle(TItem item, string key, bool expand, BitAccordionToggleReason reason) + { + if (_expandedKeys.Contains(key) == expand) return false; + + if (OnToggling.HasDelegate) + { + // The callback is awaited, so a second click - or a Toggle call while a confirmation prompt is + // still open - would otherwise start a change of its own alongside the first one. + if (_isToggling) return false; + + _isToggling = true; + _togglingKey = key; + + // Nothing toggles the list while the callback is running, so the header of the item it was + // asked about says as much - aria-busy for a screen reader, a busy cursor for a pointer - + // rather than going on looking like a toggle that answers at once. + await RefreshAndRender(); + + try { - // Collapse the currently expanded item(s) in single-expand mode. - foreach (var otherKey in _expandedKeys.ToArray()) - { - if (otherKey == key) continue; - - _expandedKeys.Remove(otherKey); - var otherItem = _items.FirstOrDefault(i => GetItemKey(i) == otherKey); - if (otherItem is not null) - { - SetIsExpanded(otherItem, false); - await OnCollapse.InvokeAsync(otherItem); - await OnToggle.InvokeAsync(otherItem); - } - } + var args = new BitAccordionListToggleArgs(item, key, expand, reason); + + await OnToggling.InvokeAsync(args); + + if (args.Cancel) return false; + + // The state can have moved on while the callback was awaited - the page can have driven the + // bound keys itself, or disposed the list altogether. + if (IsDisposed || _expandedKeys.Contains(key) == expand) return false; } + finally + { + _isToggling = false; + _togglingKey = null; - _expandedKeys.Add(key); + await RefreshAndRender(); + } + } + + if (expand) + { + AddExpandedKey(key); SetIsExpanded(item, true); await OnExpand.InvokeAsync(item); } else { - _expandedKeys.Remove(key); + RemoveExpandedKey(key); SetIsExpanded(item, false); await OnCollapse.InvokeAsync(item); } await OnToggle.InvokeAsync(item); - await UpdateBoundKeys(); - - // A toggle can affect other items too (single-expand mode collapses the previously expanded - // item), and the click handler runs on the clicked item's renderer, so both the registered - // options and the accordion list itself need an explicit re-render. - RefreshOptions(); - StateHasChanged(); + return true; } private void RefreshOptions() @@ -547,34 +1393,86 @@ private void RefreshOptions() } } + // The public methods are not called from an event handler, so nothing re-renders the component on their + // behalf the way Blazor does after a click, and the call can come from off the render loop altogether. + private Task RefreshAndRender() + { + if (IsDisposed) return Task.CompletedTask; + + return InvokeAsync(() => + { + RefreshOptions(); + StateHasChanged(); + }); + } + + private async Task FocusItemCore(TItem item) + { + if (_itemRefs.TryGetValue(item, out var itemRef) is false) return; + + try + { + await itemRef.FocusAsync(); + } + catch (JSDisconnectedException) { } // we can ignore this exception here + } + + private TItem? FindItem(string? key) + { + return key.HasNoValue() ? null : _items.FirstOrDefault(i => GetItemKey(i) == key); + } + private async Task UpdateBoundKeys() + { + _internalExpandedKeys = GetOrderedExpandedKeys(); + _internalExpandedKey = _internalExpandedKeys.FirstOrDefault(); + + await PushBoundKeys(); + } + + private async Task PushBoundKeys() { if (Multiple) { - _internalExpandedKeys = GetOrderedExpandedKeys(); + // The keys are handed over as a list of their own, which the page's value never is the same + // instance as - so a set it already holds would be reported back to it as a change of its own, + // and re-render the page for nothing. Where the list is a copy of that value, no push is due. + if (ExpandedKeys is not null && ExpandedKeys.SequenceEqual(_internalExpandedKeys)) return; + await AssignExpandedKeys([.. _internalExpandedKeys]); } else { - _internalExpandedKey = _expandedKeys.FirstOrDefault(); await AssignExpandedKey(_internalExpandedKey); } } private void BuildItemClassStyles() { + // The two objects are handed to every BitAccordion of the list as parameters, so a new pair of them on + // every render would re-render every item for nothing. + if (_itemClasses is not null && ReferenceEquals(_oldClasses, Classes) && ReferenceEquals(_oldStyles, Styles)) return; + + _oldClasses = Classes; + _oldStyles = Styles; + _itemClasses = new BitAccordionClassStyles { Root = Classes?.Item, Expanded = Classes?.ItemExpanded, + HeaderWrapper = Classes?.ItemHeaderWrapper, + Heading = Classes?.ItemHeading, Header = Classes?.ItemHeader, + Icon = Classes?.ItemIcon, HeaderContent = Classes?.ItemHeaderContent, Title = Classes?.ItemTitle, Description = Classes?.ItemDescription, ExpanderIconWrapper = Classes?.ItemExpanderIconWrapper, ExpanderIcon = Classes?.ItemExpanderIcon, ExpandedIcon = Classes?.ItemExpandedIcon, + Actions = Classes?.ItemActions, ContentContainer = Classes?.ItemContentContainer, + ContentWrapper = Classes?.ItemContentWrapper, Content = Classes?.ItemContent, }; @@ -582,14 +1480,19 @@ private void BuildItemClassStyles() { Root = Styles?.Item, Expanded = Styles?.ItemExpanded, + HeaderWrapper = Styles?.ItemHeaderWrapper, + Heading = Styles?.ItemHeading, Header = Styles?.ItemHeader, + Icon = Styles?.ItemIcon, HeaderContent = Styles?.ItemHeaderContent, Title = Styles?.ItemTitle, Description = Styles?.ItemDescription, ExpanderIconWrapper = Styles?.ItemExpanderIconWrapper, ExpanderIcon = Styles?.ItemExpanderIcon, ExpandedIcon = Styles?.ItemExpandedIcon, + Actions = Styles?.ItemActions, ContentContainer = Styles?.ItemContentContainer, + ContentWrapper = Styles?.ItemContentWrapper, Content = Styles?.ItemContent, }; } @@ -600,6 +1503,61 @@ internal bool IsItemExpanded(TItem item) return key.HasValue() && _expandedKeys.Contains(key!); } + // The header of the item an awaited OnToggling was asked about, and only that one: the rest of the list + // is not doing anything, it is only refusing to start something else while this one is being decided. + internal bool IsItemBusy(TItem item) + { + if (_togglingKey is null) return false; + + return GetItemKey(item) == _togglingKey; + } + + // A list built from options only knows it is empty once its options have had their turn to register, so + // the empty content of one waits for the render after the first rather than flashing on the first. + private bool _ShowEmptyContent => EmptyContent is not null + && _items.Count == 0 + && ((Options ?? ChildContent) is null || _hasRendered); + + // A label on a plain container is dropped by a screen reader, so the list that carries one says what it + // is. It is rendered before the splatted attributes, so a role the page sets itself still wins over it. + private string? _Role => AriaLabel.HasValue() ? "group" : null; + + // The header of the one panel that has to stay open reports itself as aria-disabled, the way the WAI-ARIA + // authoring practices ask a header whose panel cannot be collapsed to. + internal bool GetItemIsReadOnly(TItem item) + { + if (GetReadOnly(item) ?? ReadOnly) return true; + + return Collapsible is false && _expandedKeys.Count <= 1 && IsItemExpanded(item); + } + + internal bool GetItemHideExpanderIcon(TItem item) + { + return GetHideExpanderIcon(item) ?? HideExpanderIcon; + } + + internal string? GetItemHeaderAriaLabel(TItem item) + { + if (item is BitAccordionListItem listItem) + { + return listItem.HeaderAriaLabel; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.HeaderAriaLabel; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.HeaderAriaLabel.Selector is not null) + { + return NameSelectors.HeaderAriaLabel.Selector!(item); + } + + return item.GetValueFromProperty(NameSelectors.HeaderAriaLabel.Name); + } + internal RenderFragment? GetItemHeaderTemplate(TItem item) { var itemTemplate = GetHeaderTemplate(item); @@ -613,6 +1571,35 @@ internal bool IsItemExpanded(TItem item) return null; } + internal RenderFragment? GetItemTitleTemplate(TItem item) + { + var itemTemplate = GetTitleTemplate(item); + if (itemTemplate is not null) return itemTemplate(item); + + return TitleTemplate is not null ? TitleTemplate(item) : null; + } + + internal RenderFragment? GetItemExpanderTemplate(TItem item) + { + var itemTemplate = GetExpanderTemplate(item); + if (itemTemplate is not null) return _ => itemTemplate(item); + + if (ExpanderTemplate is not null) + { + return _ => ExpanderTemplate(item); + } + + return null; + } + + internal RenderFragment? GetItemActions(TItem item) + { + var itemActions = GetActions(item); + if (itemActions is not null) return itemActions(item); + + return ActionsTemplate is not null ? ActionsTemplate(item) : null; + } + internal RenderFragment? GetItemBody(TItem item) { // The option's plain inline content (ChildContent) is rendered as-is. @@ -642,12 +1629,42 @@ internal bool IsItemExpanded(TItem item) return GetExpanderIconName(item) ?? ExpanderIconName; } + internal BitIconInfo? GetItemExpandedExpanderIcon(TItem item) + { + return GetExpandedExpanderIcon(item) ?? ExpandedExpanderIcon; + } + + internal string? GetItemExpandedExpanderIconName(TItem item) + { + return GetExpandedExpanderIconName(item) ?? ExpandedExpanderIconName; + } + + internal BitIconInfo? GetItemIcon(TItem item) + { + return GetIcon(item); + } + + internal string? GetItemIconName(TItem item) + { + return GetIconName(item); + } + internal string? GetItemKey(TItem? item) { if (item is null) return null; + var key = GetDeclaredKey(item); + if (key.HasValue()) return key; + + // An item that carries no key of its own - a custom type whose key property is computed, read-only or + // simply not there - is given a generated one that is kept beside it rather than written into it. + return _fallbackKeys.TryGetValue(item, out var fallback) ? fallback : null; + } + + private string? GetDeclaredKey(TItem item) + { if (item is BitAccordionListItem listItem) { return listItem.Key; @@ -682,9 +1699,7 @@ private void SetItemKey(TItem item, string value) return; } - if (NameSelectors is null) return; - - item.SetValueToProperty(NameSelectors.Key.Name, value); + _fallbackKeys[item] = value; } internal string? GetClass(TItem? item) @@ -851,6 +1866,102 @@ private void SetIsExpanded(TItem item, bool value) item.SetValueToProperty(NameSelectors.IsExpanded.Name, value); } + private bool? GetReadOnly(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.ReadOnly; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.ReadOnly; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.ReadOnly.Selector is not null) + { + return NameSelectors.ReadOnly.Selector!(item); + } + + return item.GetValueFromProperty(NameSelectors.ReadOnly.Name); + } + + private bool? GetHideExpanderIcon(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.HideExpanderIcon; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.HideExpanderIcon; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.HideExpanderIcon.Selector is not null) + { + return NameSelectors.HideExpanderIcon.Selector!(item); + } + + return item.GetValueFromProperty(NameSelectors.HideExpanderIcon.Name); + } + + private BitIconInfo? GetIcon(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.Icon; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.Icon; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.Icon.Selector is not null) + { + return NameSelectors.Icon.Selector!(item); + } + + return item.GetValueFromProperty(NameSelectors.Icon.Name); + } + + private string? GetIconName(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.IconName; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.IconName; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.IconName.Selector is not null) + { + return NameSelectors.IconName.Selector!(item); + } + + return item.GetValueFromProperty(NameSelectors.IconName.Name); + } + private BitIconInfo? GetExpanderIcon(TItem? item) { if (item is null) return null; @@ -899,6 +2010,78 @@ private void SetIsExpanded(TItem item, bool value) return item.GetValueFromProperty(NameSelectors.ExpanderIconName.Name); } + private BitIconInfo? GetExpandedExpanderIcon(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.ExpandedExpanderIcon; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.ExpandedExpanderIcon; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.ExpandedExpanderIcon.Selector is not null) + { + return NameSelectors.ExpandedExpanderIcon.Selector!(item); + } + + return item.GetValueFromProperty(NameSelectors.ExpandedExpanderIcon.Name); + } + + private string? GetExpandedExpanderIconName(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.ExpandedExpanderIconName; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.ExpandedExpanderIconName; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.ExpandedExpanderIconName.Selector is not null) + { + return NameSelectors.ExpandedExpanderIconName.Selector!(item); + } + + return item.GetValueFromProperty(NameSelectors.ExpandedExpanderIconName.Name); + } + + private RenderFragment? GetActions(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.Actions as RenderFragment; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.Actions as RenderFragment; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.Actions.Selector is not null) + { + return NameSelectors.Actions.Selector!(item); + } + + return item.GetValueFromProperty?>(NameSelectors.Actions.Name); + } + private RenderFragment? GetBody(TItem? item) { if (item is null) return null; @@ -947,7 +2130,55 @@ private void SetIsExpanded(TItem item, bool value) return item.GetValueFromProperty?>(NameSelectors.HeaderTemplate.Name); } - private void InvokeItemClick(TItem item) + private RenderFragment? GetTitleTemplate(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.TitleTemplate as RenderFragment; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.TitleTemplate as RenderFragment; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.TitleTemplate.Selector is not null) + { + return NameSelectors.TitleTemplate.Selector!(item); + } + + return item.GetValueFromProperty?>(NameSelectors.TitleTemplate.Name); + } + + private RenderFragment? GetExpanderTemplate(TItem? item) + { + if (item is null) return null; + + if (item is BitAccordionListItem listItem) + { + return listItem.ExpanderTemplate as RenderFragment; + } + + if (item is BitAccordionListOption listOption) + { + return listOption.ExpanderTemplate as RenderFragment; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.ExpanderTemplate.Selector is not null) + { + return NameSelectors.ExpanderTemplate.Selector!(item); + } + + return item.GetValueFromProperty?>(NameSelectors.ExpanderTemplate.Name); + } + + private async Task InvokeItemClick(TItem item) { if (item is BitAccordionListItem listItem) { @@ -957,7 +2188,7 @@ private void InvokeItemClick(TItem item) if (item is BitAccordionListOption listOption) { - _ = listOption.OnClick.InvokeAsync(listOption); + await listOption.OnClick.InvokeAsync(listOption); return; } @@ -972,4 +2203,36 @@ private void InvokeItemClick(TItem item) item.GetValueFromProperty?>(NameSelectors.OnClick.Name)?.Invoke(item); } } + + + + protected override async ValueTask DisposeAsync(bool disposing) + { + if (disposing && _preventKeysRegistered) + { + _preventKeysRegistered = false; + + try + { + await _js.BitExtrasDisposePreventKeys(RootElement); + } + catch (JSDisconnectedException) { } // we can ignore this exception here + catch (ObjectDisposedException) { } // we can ignore this exception here + } + + await base.DisposeAsync(disposing); + } + + + + // The items are held by identity: two items of a type that compares by value are still two panels of the + // list, each with its own key and its own expanded state. + private sealed class ReferenceComparer : IEqualityComparer + { + internal static readonly ReferenceComparer Instance = new(); + + public bool Equals(TItem? x, TItem? y) => ReferenceEquals(x, y); + + public int GetHashCode(TItem obj) => RuntimeHelpers.GetHashCode(obj); + } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss index 11dbd451c4..f88f82b519 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss @@ -7,3 +7,13 @@ flex-flow: column nowrap; gap: spacing(1); } + +// The three wrappers the list puts around the parts of an item - one to know which item a key was pressed on, +// two to keep the keys pressed inside the panel and inside the actions from reaching it - are there for the +// events alone, so they generate no box at all and leave the layout of the item exactly as the accordion +// draws it. +.bit-acl-itm, +.bit-acl-bdy, +.bit-acl-act { + display: contents; +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs index 046d1c3598..29943d0ac4 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs @@ -20,11 +20,28 @@ public class BitAccordionListClassStyles /// public string? ItemExpanded { get; set; } + /// + /// Custom CSS classes/styles for the header wrapper of each accordion item of the BitAccordionList, + /// which holds the heading and the actions. + /// + public string? ItemHeaderWrapper { get; set; } + + /// + /// Custom CSS classes/styles for the heading element of each accordion item of the BitAccordionList + /// that wraps the header button. + /// + public string? ItemHeading { get; set; } + /// /// Custom CSS classes/styles for the header of each accordion item of the BitAccordionList. /// public string? ItemHeader { get; set; } + /// + /// Custom CSS classes/styles for the icon at the start of the header of each accordion item of the BitAccordionList. + /// + public string? ItemIcon { get; set; } + /// /// Custom CSS classes/styles for the header content of each accordion item of the BitAccordionList. /// @@ -55,11 +72,22 @@ public class BitAccordionListClassStyles /// public string? ItemExpandedIcon { get; set; } + /// + /// Custom CSS classes/styles for the actions of each accordion item of the BitAccordionList, rendered beside the header. + /// + public string? ItemActions { get; set; } + /// /// Custom CSS classes/styles for the content container of each accordion item of the BitAccordionList. /// public string? ItemContentContainer { get; set; } + /// + /// Custom CSS classes/styles for the content wrapper of each accordion item of the BitAccordionList, + /// which clips the content while it collapses. + /// + public string? ItemContentWrapper { get; set; } + /// /// Custom CSS classes/styles for the content of each accordion item of the BitAccordionList. /// diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs index 347cd7a9af..56daac5aec 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs @@ -5,6 +5,13 @@ namespace Bit.BlazorUI; /// public class BitAccordionListItem { + /// + /// The content rendered beside the header of the item, outside of the toggle button and of the heading + /// it sits in, so that it can hold its own interactive elements (a menu, a delete button, a switch). + /// The context value provides the item itself. + /// + public RenderFragment? Actions { get; set; } + /// /// The custom CSS classes of the item. /// @@ -15,6 +22,19 @@ public class BitAccordionListItem /// public string? Description { get; set; } + /// + /// Gets or sets the icon to show in place of the expander icon while the item is expanded, using custom + /// CSS classes for external icon libraries. + /// Takes precedence over when both are set. + /// + public BitIconInfo? ExpandedExpanderIcon { get; set; } + + /// + /// Gets or sets the name of the icon, from the built-in Fluent UI icons, to show in place of the expander + /// icon while the item is expanded. + /// + public string? ExpandedExpanderIconName { get; set; } + /// /// Gets or sets the icon to display as the expander using custom CSS classes for external icon libraries. /// Takes precedence over when both are set. @@ -26,16 +46,45 @@ public class BitAccordionListItem /// public string? ExpanderIconName { get; set; } + /// + /// The custom content to render in place of the expander icon of the item, leaving the rest of the header + /// as it is. The context value provides the item itself. + /// + public RenderFragment? ExpanderTemplate { get; set; } + /// /// The content (body) of the item that is shown when the item is expanded. The context value provides the item itself. /// public RenderFragment? Body { get; set; } + /// + /// The accessible label of the toggle button in the header of the item, for a header whose own content does + /// not name it - an icon-only header template, most of all. + /// + public string? HeaderAriaLabel { get; set; } + /// /// The custom template for the header of the item. The context value provides the item itself. /// public RenderFragment? HeaderTemplate { get; set; } + /// + /// Removes the expander icon from the header of the item, overriding the value of the AccordionList. + /// + public bool? HideExpanderIcon { get; set; } + + /// + /// Gets or sets the icon to display at the start of the header of the item using custom CSS classes for + /// external icon libraries. Takes precedence over when both are set. + /// + public BitIconInfo? Icon { get; set; } + + /// + /// Gets or sets the name of the icon to display at the start of the header of the item from the built-in + /// Fluent UI icons. + /// + public string? IconName { get; set; } + /// /// Whether or not the item is enabled. /// @@ -56,6 +105,12 @@ public class BitAccordionListItem /// public Action? OnClick { get; set; } + /// + /// Leaves the item where it is: its header keeps its colors and its place in the tab order, but it no + /// longer answers the pointer or the keyboard. Overrides the value of the AccordionList. + /// + public bool? ReadOnly { get; set; } + /// /// The custom value for the style attribute of the item. /// @@ -65,4 +120,10 @@ public class BitAccordionListItem /// The title (header text) of the item. /// public string? Title { get; set; } + + /// + /// The custom content to render in place of the of the item, leaving the rest of the + /// header as it is. The context value provides the item itself. + /// + public RenderFragment? TitleTemplate { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs index 27fa7fa0a2..3431022d55 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs @@ -5,6 +5,11 @@ namespace Bit.BlazorUI; /// public class BitAccordionListNameSelectors { + /// + /// Actions field name and selector of the custom input class. + /// + public BitNameSelectorPair?> Actions { get; set; } = new(nameof(BitAccordionListItem.Actions)); + /// /// The CSS Class field name and selector of the custom input class. /// @@ -15,6 +20,16 @@ public class BitAccordionListNameSelectors /// public BitNameSelectorPair Description { get; set; } = new(nameof(BitAccordionListItem.Description)); + /// + /// ExpandedExpanderIcon field name and selector of the custom input class. + /// + public BitNameSelectorPair ExpandedExpanderIcon { get; set; } = new(nameof(BitAccordionListItem.ExpandedExpanderIcon)); + + /// + /// ExpandedExpanderIconName field name and selector of the custom input class. + /// + public BitNameSelectorPair ExpandedExpanderIconName { get; set; } = new(nameof(BitAccordionListItem.ExpandedExpanderIconName)); + /// /// ExpanderIcon field name and selector of the custom input class. /// @@ -25,16 +40,41 @@ public class BitAccordionListNameSelectors /// public BitNameSelectorPair ExpanderIconName { get; set; } = new(nameof(BitAccordionListItem.ExpanderIconName)); + /// + /// ExpanderTemplate field name and selector of the custom input class. + /// + public BitNameSelectorPair?> ExpanderTemplate { get; set; } = new(nameof(BitAccordionListItem.ExpanderTemplate)); + /// /// Body field name and selector of the custom input class. /// public BitNameSelectorPair?> Body { get; set; } = new(nameof(BitAccordionListItem.Body)); + /// + /// HeaderAriaLabel field name and selector of the custom input class. + /// + public BitNameSelectorPair HeaderAriaLabel { get; set; } = new(nameof(BitAccordionListItem.HeaderAriaLabel)); + /// /// HeaderTemplate field name and selector of the custom input class. /// public BitNameSelectorPair?> HeaderTemplate { get; set; } = new(nameof(BitAccordionListItem.HeaderTemplate)); + /// + /// HideExpanderIcon field name and selector of the custom input class. + /// + public BitNameSelectorPair HideExpanderIcon { get; set; } = new(nameof(BitAccordionListItem.HideExpanderIcon)); + + /// + /// Icon field name and selector of the custom input class. + /// + public BitNameSelectorPair Icon { get; set; } = new(nameof(BitAccordionListItem.Icon)); + + /// + /// IconName field name and selector of the custom input class. + /// + public BitNameSelectorPair IconName { get; set; } = new(nameof(BitAccordionListItem.IconName)); + /// /// IsEnabled field name and selector of the custom input class. /// @@ -55,6 +95,11 @@ public class BitAccordionListNameSelectors /// public BitNameSelectorPair?> OnClick { get; set; } = new(nameof(BitAccordionListItem.OnClick)); + /// + /// ReadOnly field name and selector of the custom input class. + /// + public BitNameSelectorPair ReadOnly { get; set; } = new(nameof(BitAccordionListItem.ReadOnly)); + /// /// The CSS Style field name and selector of the custom input class. /// @@ -64,4 +109,9 @@ public class BitAccordionListNameSelectors /// Title field name and selector of the custom input class. /// public BitNameSelectorPair Title { get; set; } = new(nameof(BitAccordionListItem.Title)); + + /// + /// TitleTemplate field name and selector of the custom input class. + /// + public BitNameSelectorPair?> TitleTemplate { get; set; } = new(nameof(BitAccordionListItem.TitleTemplate)); } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs index ad8c7a4161..405b7640a1 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs @@ -8,9 +8,16 @@ public partial class BitAccordionListOption : ComponentBase, IAsyncDisposable private bool _disposed; - [CascadingParameter] protected BitAccordionList Parent { get; set; } = default!; + [CascadingParameter] protected BitAccordionList? Parent { get; set; } + /// + /// The content rendered beside the header of the option, outside of the toggle button and of the heading + /// it sits in, so that it can hold its own interactive elements (a menu, a delete button, a switch). + /// The context value provides the option itself. + /// + [Parameter] public RenderFragment? Actions { get; set; } + /// /// The custom CSS classes of the option. /// @@ -21,6 +28,19 @@ public partial class BitAccordionListOption : ComponentBase, IAsyncDisposable /// [Parameter] public string? Description { get; set; } + /// + /// Gets or sets the icon to show in place of the expander icon while the option is expanded, using custom + /// CSS classes for external icon libraries. + /// Takes precedence over when both are set. + /// + [Parameter] public BitIconInfo? ExpandedExpanderIcon { get; set; } + + /// + /// Gets or sets the name of the icon, from the built-in Fluent UI icons, to show in place of the expander + /// icon while the option is expanded. + /// + [Parameter] public string? ExpandedExpanderIconName { get; set; } + /// /// Gets or sets the icon to display as the expander using custom CSS classes for external icon libraries. /// Takes precedence over when both are set. @@ -32,6 +52,12 @@ public partial class BitAccordionListOption : ComponentBase, IAsyncDisposable /// [Parameter] public string? ExpanderIconName { get; set; } + /// + /// The custom content to render in place of the expander icon of the option, leaving the rest of the header + /// as it is. The context value provides the option itself. + /// + [Parameter] public RenderFragment? ExpanderTemplate { get; set; } + /// /// The content (body) of the option that is shown when the option is expanded. The context value provides the option itself. /// @@ -43,11 +69,34 @@ public partial class BitAccordionListOption : ComponentBase, IAsyncDisposable /// [Parameter] public RenderFragment? ChildContent { get; set; } + /// + /// The accessible label of the toggle button in the header of the option, for a header whose own content does + /// not name it - an icon-only header template, most of all. + /// + [Parameter] public string? HeaderAriaLabel { get; set; } + /// /// The custom template for the header of the option. The context value provides the option itself. /// [Parameter] public RenderFragment? HeaderTemplate { get; set; } + /// + /// Removes the expander icon from the header of the option, overriding the value of the AccordionList. + /// + [Parameter] public bool? HideExpanderIcon { get; set; } + + /// + /// Gets or sets the icon to display at the start of the header of the option using custom CSS classes for + /// external icon libraries. Takes precedence over when both are set. + /// + [Parameter] public BitIconInfo? Icon { get; set; } + + /// + /// Gets or sets the name of the icon to display at the start of the header of the option from the built-in + /// Fluent UI icons. + /// + [Parameter] public string? IconName { get; set; } + /// /// Whether or not the option is enabled. /// @@ -68,6 +117,12 @@ public partial class BitAccordionListOption : ComponentBase, IAsyncDisposable /// [Parameter] public EventCallback OnClick { get; set; } + /// + /// Leaves the option where it is: its header keeps its colors and its place in the tab order, but it no + /// longer answers the pointer or the keyboard. Overrides the value of the AccordionList. + /// + [Parameter] public bool? ReadOnly { get; set; } + /// /// The custom value for the style attribute of the option. /// @@ -78,6 +133,12 @@ public partial class BitAccordionListOption : ComponentBase, IAsyncDisposable /// [Parameter] public string? Title { get; set; } + /// + /// The custom content to render in place of the of the option, leaving the rest of the + /// header as it is. The context value provides the option itself. + /// + [Parameter] public RenderFragment? TitleTemplate { get; set; } + internal void InternalStateHasChanged() { @@ -88,16 +149,32 @@ internal void InternalStateHasChanged() protected override async Task OnInitializedAsync() { - if (Parent is not null) - { - Parent.RegisterOption(this); - } + // An option outside of an accordion list, or inside one closed over another item type, receives no + // cascading parent and would otherwise render nothing at all without saying why. + if (Parent is null) + { + throw new InvalidOperationException( + $"{nameof(BitAccordionListOption)} must be placed inside a BitAccordionList whose TItem is {nameof(BitAccordionListOption)}."); + } + + Parent.RegisterOption(this); await base.OnInitializedAsync(); } // Renders the option's item in place, so the rendered order of the items always follows the // markup order of the options, even when an option is added or removed conditionally later on. + protected override void OnParametersSet() + { + // The list hands its options their parameters in markup order, every one of them, every time it + // renders - which is the order the list wants its items in, and not the order they registered + // themselves in once one of them has been added conditionally. A render of the option's own is no + // use here: only the option that was just added has one when it is added. + Parent?.ReportOptionOrder(this); + + base.OnParametersSet(); + } + protected override void BuildRenderTree(RenderTreeBuilder builder) { if (Parent is null) return; @@ -118,12 +195,12 @@ protected virtual async ValueTask DisposeAsync(bool disposing) { if (disposing is false || _disposed) return; - if (Parent is not null) - { + if (Parent is not null) + { // Await the unregistration so that any UpdateBoundKeys or ExpandedKey(s) callbacks it // triggers are awaited and observed, rather than running as fire-and-forget. - await Parent.UnregisterOption(this); - } + await Parent.UnregisterOption(this); + } _disposed = true; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListToggleArgs.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListToggleArgs.cs new file mode 100644 index 0000000000..cb9c172f16 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListToggleArgs.cs @@ -0,0 +1,57 @@ +namespace Bit.BlazorUI; + +/// +/// Arguments for the OnToggling callback of . +/// Set to true to leave the item as it is. +/// +public class BitAccordionListToggleArgs where TItem : class +{ + /// + /// Creates a new instance of . + /// + /// + /// The item that is about to expand or collapse. + /// + /// + /// The key of the item that is about to expand or collapse. + /// + /// + /// Whether the item is about to expand. + /// + /// + /// What made the item expand or collapse. + /// + public BitAccordionListToggleArgs(TItem item, string? key, bool isExpanding, BitAccordionToggleReason reason) + { + Item = item; + Key = key; + IsExpanding = isExpanding; + Reason = reason; + } + + /// + /// The item that is about to expand or collapse. + /// + public TItem Item { get; } + + /// + /// The key of the item that is about to expand or collapse. + /// + public string? Key { get; } + + /// + /// The state the item is about to move to: true while it is expanding, false while it is collapsing. + /// + public bool IsExpanding { get; } + + /// + /// What made the item expand or collapse: a click on its header, or a call to one of the + /// Expand, Collapse, Toggle, ExpandAll and CollapseAll methods of the AccordionList. + /// + public BitAccordionToggleReason Reason { get; } + + /// + /// Set to true to cancel the expansion or the collapse and leave the item as it is. + /// + public bool Cancel { get; set; } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/_BitAccordionListItem.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/_BitAccordionListItem.razor index 0140f10a7a..3494e4930d 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/_BitAccordionListItem.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/_BitAccordionListItem.razor @@ -4,23 +4,56 @@ @{ var isEnabled = AccordionList.IsEnabled && AccordionList.GetIsEnabled(Item); var headerTemplate = AccordionList.GetItemHeaderTemplate(Item); + var titleTemplate = AccordionList.GetItemTitleTemplate(Item); + var expanderTemplate = AccordionList.GetItemExpanderTemplate(Item); } - - @AccordionList.GetItemBody(Item) - +@* The wrapper generates no box of its own (display: contents), so it leaves the layout of the list exactly + as it was while giving the keyboard navigation of the AccordionList something to listen on that knows + which item the key was pressed on - which the list root, shared by every item, could not tell. *@ +
+ + @* A key pressed inside the panel belongs to whatever the panel holds - a text field, a nested list - + so it is kept from reaching the navigation handler on the wrapper above. *@ +
+ @AccordionList.GetItemBody(Item) +
+
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/_BitAccordionListItem.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/_BitAccordionListItem.razor.cs index 925952b803..9e7a390c5b 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/_BitAccordionListItem.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/_BitAccordionListItem.razor.cs @@ -1,8 +1,103 @@ namespace Bit.BlazorUI; -public partial class _BitAccordionListItem : ComponentBase where TItem : class +public partial class _BitAccordionListItem : ComponentBase, IDisposable where TItem : class { + private bool _skipRender; + private TItem? _registeredItem; + private BitAccordion? _accordion; + [Parameter] public TItem Item { get; set; } = default!; [Parameter] public BitAccordionList AccordionList { get; set; } = default!; + + + + internal ValueTask FocusAsync() => _accordion?.FocusAsync() ?? ValueTask.CompletedTask; + + // The root element of the accordion the item renders, which is the box the list scrolls into view: the + // wrapper around it generates none of its own (display: contents) and could not be scrolled to. + internal ElementReference? GetElement() => _accordion?.RootElement; + + + + protected override void OnParametersSet() + { + // A render the list asks for is never the one the keyboard bookkeeping below is trying to skip. + _skipRender = false; + + base.OnParametersSet(); + } + + // The keydown handler on the wrapper is bookkeeping for the list rather than a state change of this item, + // so the render Blazor runs after every one of its event handlers is skipped: without this, every key + // pressed on a header - Tab included - would re-render the whole item and its panel for nothing. + protected override bool ShouldRender() + { + if (_skipRender is false) return true; + + _skipRender = false; + + return false; + } + + protected override void OnAfterRender(bool firstRender) + { + // The list keeps a reference of every item it renders so that it can move the focus to it. The item + // itself can be swapped for another one on a later render, so the old registration is dropped first. + if (ReferenceEquals(_registeredItem, Item) is false) + { + if (_registeredItem is not null) + { + AccordionList.UnregisterItem(_registeredItem); + } + + _registeredItem = Item; + + AccordionList.RegisterItem(Item, this); + } + + base.OnAfterRender(firstRender); + } + + private RenderFragment? BuildActions() + { + var actions = AccordionList.GetItemActions(Item); + + if (actions is null) return null; + + // The actions sit outside of the panel, so they need a stop of their own to keep the keys pressed on + // whatever they hold - a menu, a switch - from reaching the navigation handler on the wrapper. + return builder => + { + builder.OpenElement(0, "div"); + builder.AddAttribute(1, "class", "bit-acl-act"); + builder.AddEventStopPropagationAttribute(2, "onkeydown", true); + builder.AddContent(3, actions); + builder.CloseElement(); + }; + } + + private async Task HandleOnKeyDown(KeyboardEventArgs e) + { + _skipRender = true; + + // A panel that scrolls (MaxHeight) is a tab stop of its own, and the arrow keys pressed on it are its + // own scroll. The stop inside it never sees them - they are fired on the box that holds the content + // rather than inside it - so the navigation steps aside for as long as the panel holds the focus, + // rather than moving the reader twice: once down the list and once down the panel. + if (_accordion?.IsContentFocused is true) return; + + await AccordionList.HandleOnItemKeyDown(e, Item); + } + + public void Dispose() + { + if (_registeredItem is not null) + { + AccordionList?.UnregisterItem(_registeredItem); + _registeredItem = null; + } + + GC.SuppressFinalize(this); + } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor index 102db220cd..f616fc13b3 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor @@ -9,12 +9,18 @@ style="@StyleBuilder.Value" class="@ClassBuilder.Value" dir="@Dir?.ToString().ToLower()"> -
+
+ @* The direction is repeated here on purpose, and the pair of it and the LOGICAL inset variables the + two side bars are sized from is what keeps each safe area on the physical edge it belongs to. This + row lays its three children out in the reading direction, so the first of them is the physically + right one in a right-to-left shell - and the inline-start inset it reads is, under the same + direction, the inset of the physical right. Take either half away and the two stop cancelling out: + the left of the screen would be inset by whatever the right of it needed. *@
-
+
@ChildContent diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor.cs index e278276e34..46b5943b05 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor.cs @@ -6,15 +6,53 @@ namespace Bit.BlazorUI; /// /// BitAppShell is an advanced container to handle the nuances of a cross-platform layout. /// +/// +/// It is the outermost element of an application: it insets the four edges of the screen by the safe +/// areas the device reports, owns the one region the application scrolls in - which is what lets a Modal, +/// a Panel or an Overlay inside it hold the right scroller - and can keep the reader's place in the pages +/// they navigate between. +///
+/// The safe area insets are read from env(safe-area-inset-*), which the browser only reports as +/// anything other than zero on a page whose viewport meta tag carries viewport-fit=cover. +///
+/// What it measures is published on its root as CSS variables, so a page can lay its own chrome out +/// against the same numbers: --bit-ash-inset-top, --bit-ash-inset-bottom, +/// --bit-ash-inset-start and --bit-ash-inset-end for the four safe areas, and +/// --bit-ash-keyboard-inset for how much of the shell the on-screen keyboard is covering. +///
[SuppressMessage("Trimming", "IL2110:Field with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.", Justification = "")] public partial class BitAppShell : BitComponentBase { + /// + /// The name the app shell cascades the element of its main (scrolling) container under, so that the + /// components which have to hold a scroller - Modal, Panel, Dialog, Overlay - can find the one the + /// application actually scrolls in without being handed it. + /// public const string Container = "BitAppShell.Container"; + /// + /// The id the main container of the app shell carries. + /// + /// + /// It is well known rather than unique because it is read before Blazor has started, by the script + /// that keeps the scrolling the reader did on the server-rendered shell. Only one element of a page + /// can carry an id, so the rare page that renders more than one app shell gives the extra ones an + /// Id of their own, off which their container ids are derived. + /// + public const string ContainerId = "BitAppShell-container"; + + private bool _subscribed; + private bool _scrollInit; + private bool _paneSetup; + private bool _autoScrolled; + private bool _keyboardSetup; private bool _locationChanged; + private string? _lastLocation; private ElementReference? _containerRef; + private BitScrollablePaneOptions? _paneOptions; + private DotNetObjectReference? _dotnetObj; @@ -26,8 +64,63 @@ public partial class BitAppShell : BitComponentBase /// /// Enables auto-scroll to the top of the main container on navigation. /// + /// + /// A navigation that only changes the fragment of the url - an in-page anchor - is left alone, since + /// scrolling to the top is the opposite of what following an anchor asks for. + /// takes precedence over this. + /// [Parameter] public bool AutoGoToTop { get; set; } + /// + /// Keeps the main container of the app shell pinned to the end of its content as the content grows. + /// + /// + /// This is what the chat, the log or the console of a shell wants: the newest content is at the end and + /// the shell stays there on its own. It pins the container as soon as it is turned on, and after that + /// only while the reader left it standing at the end - a reader who scrolled up to read something is + /// not dragged back down by the next arrival, and scrolling back to the end takes the pinning up again. + /// decides how near the end still counts as being at it, and + /// how the moves it makes are animated. + /// + [Parameter] public bool AutoScroll { get; set; } + + /// + /// How near the end of the content (in pixels) the main container has to have been left for + /// to keep pinning it there. + /// + /// + /// The default of 0 asks the reader to be at the very end, which is the strictest reading and the one a + /// chat usually wants. A larger value keeps the pinning going while they are within that many pixels of + /// it, so a line or two of slack does not count as having scrolled away. + /// + [Parameter] public int AutoScrollThreshold { get; set; } + + /// + /// Takes the height of the on-screen keyboard off the scrolling area of the app shell while it is + /// open, so the content is laid out in the room that is actually left rather than behind it. + /// + /// + /// Opening the keyboard leaves the layout viewport - and therefore every percentage height on the + /// page - exactly as it was on the platforms that need this, so a shell that is not told about it + /// goes on believing it owns a screen whose bottom is now covered. With this on, the shell publishes + /// the covered height on its root as the --bit-ash-keyboard-inset CSS variable and takes it off + /// the height of the middle, which is what brings a bottom bar declared inside the shell back above + /// the keyboard. The bottom safe area inset is given up for as long as the keyboard is open, since what + /// that inset keeps clear is covered by the keyboard anyway and a band of background above it would be + /// room taken from the content for nothing. + ///
+ /// The root is also marked with the data-bit-ash-keyboard attribute while the keyboard is up - + /// which is what the chrome that hides itself while the reader is typing can be styled against - and + /// the same measurement is reported to for whatever cannot be + /// placed in CSS alone. + ///
+ /// It reports 0 - and so does nothing - wherever the browser shrinks the layout viewport itself, which + /// is every desktop browser and any page asking for interactive-widget=resizes-content, and it + /// leaves the measurement alone while the page is pinch-zoomed, since a zoomed page shrinks its visual + /// viewport in exactly the way an open keyboard does. + ///
+ [Parameter] public bool AvoidKeyboard { get; set; } + /// /// The content of the app shell. /// @@ -38,10 +131,267 @@ public partial class BitAppShell : BitComponentBase /// [Parameter] public BitAppShellClassStyles? Classes { get; set; } + /// + /// Pins the app shell to the four edges of the screen, so that it fills the window whatever height the + /// page around it has. + /// + /// + /// The app shell otherwise fills the room it is given, which means the html and the body + /// of the host page have to be given a height of their own for it to have any - the commonest reason a + /// shell is reported as having no height at all. This takes the page out of the question: the shell is + /// positioned against the viewport instead, which is what the shell of an application wants anyway, + /// since nothing is meant to be laid out around it or scrolled past it. + /// + [Parameter, ResetClassBuilder] public bool FullScreen { get; set; } + + /// + /// Reserves the room the scrollbar of the main container takes, whether or not there is anything left + /// to scroll. + /// + /// + /// This is the CSS scrollbar-gutter property, and the one scroller of an application is where it + /// earns its keep: without it, every navigation between a page long enough to scroll and a page that is + /// not moves the whole layout sideways by the width of a scrollbar. It costs nothing at all where the + /// platform draws its scrollbars over the content, which is every mobile browser. + /// + [Parameter] public BitScrollbarGutter? Gutter { get; set; } + + /// + /// Removes the bottom safe area inset of the app shell, leaving the other three where they are. + /// + /// + /// For the application that insets that one edge itself - a bottom bar padding itself by the inset so + /// that its background paints behind the home indicator, in a shell that still keeps the status bar and + /// the rounded sides clear. is the same thing for all four edges at once. + /// + [Parameter, ResetClassBuilder] public bool NoBottomInset { get; set; } + + /// + /// Removes the trailing side safe area inset of the app shell - the one on the right of a left-to-right + /// shell and on the left of a right-to-left one - leaving the other three where they are. + /// See . + /// + [Parameter, ResetClassBuilder] public bool NoEndInset { get; set; } + + /// + /// Removes the safe area insets, so the four edges of the app shell are not inset at all and the + /// content fills the whole screen. + /// + /// + /// For an application that insets its own edges - a header that pads itself by the top inset so that + /// its background paints behind the status bar - which is what an edge-to-edge layout asks for. + /// + [Parameter, ResetClassBuilder] public bool NoInsets { get; set; } + + /// + /// Prevents the reader from scrolling the main container of the app shell at all. + /// + /// + /// The content that overflows is clipped rather than reachable. The scrolling API of this component + /// still moves the container, since overflow: hidden only stops the reader's own gestures. + /// + [Parameter] public bool NoScroll { get; set; } + + /// + /// Removes the leading side safe area inset of the app shell - the one on the left of a left-to-right + /// shell and on the right of a right-to-left one - leaving the other three where they are. + /// See . + /// + [Parameter, ResetClassBuilder] public bool NoStartInset { get; set; } + + /// + /// Removes the top safe area inset of the app shell, leaving the other three where they are. + /// + /// + /// For the application that insets that one edge itself - a header padding itself by the inset so that + /// its background paints behind the status bar, in a shell that still keeps the home indicator clear, + /// which is the commonest half of an edge-to-edge layout. See . + /// + [Parameter, ResetClassBuilder] public bool NoTopInset { get; set; } + + /// + /// Callback for how much of the app shell the on-screen keyboard covers, in pixels, raised as that + /// changes and with 0 as the keyboard closes. + /// + /// + /// It is what publishes as the --bit-ash-keyboard-inset CSS + /// variable, handed to the page as a number as well so the chrome that cannot be placed in CSS alone - + /// a map to re-center, a list to keep the selected row of in view - can be moved with it. Nothing is + /// measured, and so nothing is reported, on a shell that has not asked to avoid the keyboard. + /// + [Parameter] public EventCallback OnKeyboardInsetChanged { get; set; } + + /// + /// Callback for when the main container of the app shell reaches the bottom of its content. + /// + /// + /// It is raised once per arrival rather than on every frame that stays there, and how near the bottom + /// counts as having reached it is . + /// + [Parameter] public EventCallback OnReachedBottom { get; set; } + /// + /// Callback for when the main container of the app shell reaches the visual left edge of its content. + /// See . + /// + /// + /// The edge is the one on the screen rather than the one in reading order, so it is the same edge in a + /// right-to-left shell. + /// + [Parameter] public EventCallback OnReachedLeft { get; set; } + + /// + /// Callback for when the main container of the app shell reaches the visual right edge of its content. + /// See . + /// + [Parameter] public EventCallback OnReachedRight { get; set; } + + + /// + /// Callback for when the main container of the app shell reaches the top of its content. + /// See . + /// + [Parameter] public EventCallback OnReachedTop { get; set; } + + /// + /// Callback for the scroll position of the main container of the app shell, raised as it is scrolled. + /// + /// + /// Reporting costs a listener and a measurement per frame of every scroll, so nothing is reported at + /// all until one of the scroll callbacks is given a handler. Use to + /// report less often than once per frame. + /// + [Parameter] public EventCallback OnScroll { get; set; } + + /// + /// Callback for when a scroll of the main container of the app shell comes to a stop. + /// + [Parameter] public EventCallback OnScrollEnd { get; set; } + + /// + /// Callback for when a scroll of the main container of the app shell begins. + /// + [Parameter] public EventCallback OnScrollStart { get; set; } + + /// + /// What the main container of the app shell does with content that overflows it sideways. + /// + /// + /// The main container scrolls along both axes, which is what an application laying a page out wider + /// than the screen needs. Set this to to clip that overflow instead, + /// so the one element a few pixels too wide cannot leave the whole application scrollable sideways - + /// the commonest layout bug of a mobile web app. takes both axes away at once + /// and wins over this. + /// + [Parameter] public BitOverflow? OverflowX { get; set; } + + /// + /// What the main container of the app shell does with content that overflows it downwards. + /// See . + /// + [Parameter] public BitOverflow? OverflowY { get; set; } + + /// + /// Determines what happens when the main container of the app shell is scrolled past its edge. + /// + /// + /// Left unset, the app shell behaves as , which is what an + /// application-like layout wants: no scroll chaining out of the shell, and no pull-to-refresh or + /// rubber-banding of the page behind it. Set it to to give the + /// platform's own overscroll affordances back to a shell that is really a web page. + /// + [Parameter] public BitOverscroll? Overscroll { get; set; } + /// /// Persists scroll position of the main container and restores it on navigation. /// + /// + /// The positions are kept per url in session storage, so they survive a reload and are gone when the + /// tab is - forgets them sooner. A navigation that only changes the + /// fragment of the url is left alone, so an in-page anchor still works. It takes precedence over + /// . + ///
+ /// The store belongs to the page rather than to this component, so it is the one app shell of an + /// application that is meant to ask for it: a second shell doing so on the same page would take the + /// store over from the first. + ///
[Parameter] public bool PersistScroll { get; set; } + /// + /// Keeps the reader's place when content is added above what they are looking at. + /// + /// + /// This is the other half of an endless list: a page of older messages arriving at the top of a + /// conversation is as tall as the messages in it, and without this it pushes what the reader was + /// reading that far down the screen. With it the container is moved down by exactly what arrived, so + /// what they were looking at does not move at all. + ///
+ /// Every engine but WebKit already does this on its own (it is the CSS overflow-anchor + /// behavior), so this changes nothing where the browser is anchoring the container and brings the rest + /// - Safari, most of all - up to the same behavior. It is worth pairing with + /// and a of about a screenful, so the fetch starts before the reader is at + /// the top rather than once they are. + ///
+ [Parameter] public bool PreserveScroll { get; set; } + + + /// + /// How near an edge (in pixels) counts as having reached it, for and + /// . + /// + [Parameter] public int ReachOffset { get; set; } + + /// + /// The scroll behavior of the main container of the app shell. + /// + /// + /// It decides how every move the container is not dragged to by the reader is made: the scrolling API + /// of this component, a fragment navigation into it, and the browser bringing a focused element into + /// view. The default is , which is taken back off on its own + /// under the reduced motion preference unless ForceAnimation is set. + /// + [Parameter] public BitScrollBehavior? ScrollBehavior { get; set; } + /// + /// The room the main container of the app shell keeps between its edges and anything scrolled into + /// view inside it, as any CSS length. + /// + /// + /// This is the CSS scroll-padding property, and it is what keeps a header stuck to the top of + /// the shell from covering whatever was just scrolled to - by a fragment navigation, by the browser + /// bringing a focused field into view, or by , which reads it as well so + /// that the moves this component makes leave the same room the browser's own do. The other scrolling + /// methods take an absolute position or a distance and are left alone by it. + ///
+ /// A shell whose header is the height of the top safe area plus a bar of its own can say so: + /// ScrollPadding="calc(var(--bit-ash-inset-top) + 3rem) 0 0 0". + ///
+ [Parameter] public string? ScrollPadding { get; set; } + + + /// + /// The shortest interval (in milliseconds) between two reports. + /// The default of 0 reports once per animation frame. + /// + [Parameter] public int ScrollThrottle { get; set; } + + /// + /// Sizes the four inset bars from the largest safe areas the device can ask for rather than from the + /// ones it is asking for right now, so the layout is not relaid out as the browser's own chrome slides + /// in and out. + /// + /// + /// The insets a browser reports are not constants: an edge-to-edge Chrome on Android retracts its + /// bottom bar as the reader scrolls down and brings it back on the way up, and the bottom inset follows + /// it the whole way - so the bar sized from it, and everything laid out against it, is moved on every + /// frame of that slide. With this on the shell is sized from the static maximums instead + /// (env(safe-area-max-inset-*)): the layout is laid out once, for the room left when nothing is + /// retracted, and the browser slides its own chrome over the background of an inset bar rather than + /// over the content. It costs that much room on the screen for as long as the chrome is retracted, + /// which is the trade being made. + ///
+ /// A browser that does not report the maximums - which is every one but Chromium 135 and later, and + /// every platform whose insets do not move in the first place - is left reading the insets it does + /// report, so this changes nothing there. + ///
+ [Parameter, ResetClassBuilder] public bool StableInsets { get; set; } /// /// Custom CSS styles for different parts of the app shell. @@ -60,20 +410,173 @@ public partial class BitAppShell : BitComponentBase + /// + /// The element reference to the main container of the app shell. + /// + public ElementReference? ContainerRef => _containerRef; + + /// + /// The id of the main container element of this app shell. + /// + /// + /// It is unless an Id was given to the app shell, in which case it + /// is that id with -container after it - which is how a page that renders more than one app + /// shell keeps each container id to itself. + /// + public string MainContainerId => Id.HasValue() ? $"{Id}-container" : ContainerId; + + + /// /// Scrolls the main container to top. /// + /// + /// How the move is made. When it is not given, the of the app shell + /// decides, which honors the reduced motion preference. + /// public async Task GoToTop(BitScrollBehavior? behavior = null) { if (_containerRef.HasValue is false) return; - await _js.BitExtrasGoToTop(_containerRef.Value, behavior); + await InvokeJs(() => _js.BitExtrasGoToTop(_containerRef!.Value, behavior)); } /// - /// The element reference to the main container of the app shell. + /// Scrolls the main container to the bottom of its content. /// - public ElementReference? ContainerRef => _containerRef; + /// See . + public async Task GoToBottom(BitScrollBehavior? behavior = null) + { + if (_containerRef.HasValue is false) return; + + await InvokeJs(() => _js.BitExtrasGoToBottom(_containerRef!.Value, behavior)); + } + + /// + /// Scrolls the main container to a position. + /// + /// The horizontal position, or null to leave that axis where it stands. + /// The vertical position, or null to leave that axis where it stands. + /// See . + public async Task ScrollTo(double? left, double? top, BitScrollBehavior? behavior = null) + { + if (_containerRef.HasValue is false) return; + + await InvokeJs(() => _js.BitExtrasScrollTo(_containerRef!.Value, left, top, behavior)); + } + + /// + /// Scrolls the main container by an amount, from wherever it currently stands. + /// + /// How far to move sideways, in pixels. + /// How far to move up or down, in pixels. + /// See . + public async Task ScrollBy(double x, double y, BitScrollBehavior? behavior = null) + { + if (_containerRef.HasValue is false) return; + + // A NaN or an infinity is not a distance, and the serializer of the interop call refuses both, so a + // call made with one is dropped here rather than thrown out of the caller's own event handler. + if (double.IsFinite(x) is false || double.IsFinite(y) is false) return; + + await InvokeJs(() => _js.BitExtrasScrollBy(_containerRef!.Value, x, y, behavior)); + } + + /// + /// Brings an element inside the main container into view by scrolling the container itself. + /// + /// The id of the element to scroll to. + /// How much room (in pixels) to leave above it, for a sticky header of the page. + /// Whether the move is animated. Honors the reduced motion preference. + /// Where in the container the element comes to rest. + /// + /// How the move is made, which wins over both and + /// where it is given. Left out, the move is animated only where the two + /// of them agree that it should be. + /// + public async Task ScrollToElement(string elementId, + double offset = 0, + bool smooth = true, + BitScrollAlignment alignment = BitScrollAlignment.Start, + BitScrollBehavior? behavior = null) + { + if (_containerRef.HasValue is false || elementId.HasNoValue()) return; + + // The behavior is the same argument every other move of this component takes, and it wins over + // both the flag beside it and the property of the shell where it is given. Left out, the two of + // them have to agree: the flag is what this call asks for and the property is what the shell + // moves like, so a shell told to move instantly is not animated by a flag that was never set. + var animated = behavior switch + { + BitScrollBehavior.Smooth => true, + BitScrollBehavior.Instant => false, + BitScrollBehavior.Auto => ScrollBehavior is null or BitScrollBehavior.Smooth, + _ => smooth && ScrollBehavior is null or BitScrollBehavior.Smooth + }; + + await InvokeJs(() => _js.BitScrollablePaneScrollToElement(_containerRef!.Value, + elementId, + offset, + animated, + alignment.ToString().ToLowerInvariant())); + } + + /// + /// Re-measures the main container of the app shell and reports whatever has changed since it was last + /// measured. + /// + /// + /// The container watches both its own size and its content on its own, so this is only for the changes + /// neither of those can see - a web font that finished loading, an image that settled at a size the + /// markup never named - after which the edge callbacks and the pinning of are + /// brought back up to date. It does nothing on a shell that asked for none of them, since such a shell + /// has no browser side to bring up to date. + /// + public async Task Refresh() + { + if (_paneSetup is false) return; + + await InvokeJs(() => _js.BitScrollablePaneRefresh(UniqueId)); + } + + /// + /// Reads where the main container currently stands, measured in the browser. + /// + /// + /// It is a read of the element at the moment it is asked for, so it needs none of the scroll + /// callbacks to have been given a handler. + /// + public async Task GetScrollOffset() + { + if (_containerRef.HasValue is false) return null; + + try + { + return await _js.BitScrollablePaneGetOffset(_containerRef.Value); + } + catch (JSDisconnectedException) { return null; } + catch (ObjectDisposedException) { return null; } + } + + /// + /// Forgets every scroll position has kept, for the pages of this app + /// shell and of any other. + /// + /// + /// The positions are kept for the whole session, so an application that signs a user out calls this + /// to keep the next one from being put back where the previous one was. Given a url, only that one page + /// is forgotten, which is what a page whose content has been replaced under the reader - a list that was + /// filtered, a search that was run again - wants, since the position it was left at no longer points at + /// anything. + /// + /// + /// The url to forget, exactly as NavigationManager.Uri reports it. When it is not given, every + /// position is forgotten. + /// + public async Task ClearPersistedScroll(string? url = null) + { + await InvokeJs(() => _js.BitAppShellClearScrolls(url)); + } @@ -82,6 +585,28 @@ public async Task GoToTop(BitScrollBehavior? behavior = null) protected override void RegisterCssClasses() { ClassBuilder.Register(() => Classes?.Root); + + // The insets are the four bars around the main container, so the flag that removes them belongs + // on the root all four of them are sized from. + ClassBuilder.Register(() => NoInsets ? "bit-ash-nin" : string.Empty); + + // The shell is taken out of the flow of the host page and positioned against the viewport itself, + // so it has a height of its own without the page having given html and body one. + ClassBuilder.Register(() => FullScreen ? "bit-ash-fsc" : string.Empty); + + // Written before the flags that take an inset away, and the stylesheet keeps them in that order, + // so a shell asking for both is left with the edge removed rather than with the largest inset the + // device can ask for. + ClassBuilder.Register(() => StableInsets ? "bit-ash-sin" : string.Empty); + + // And each of the four can be taken back to zero on its own, for the application that insets that + // one edge itself: a header painting behind the status bar over a shell that still keeps the home + // indicator clear is an edge-to-edge layout of the top edge alone. The two side ones are the + // LOGICAL edges, so each of them stays with the reading direction the bars are laid out in. + ClassBuilder.Register(() => NoTopInset ? "bit-ash-nit" : string.Empty); + ClassBuilder.Register(() => NoBottomInset ? "bit-ash-nib" : string.Empty); + ClassBuilder.Register(() => NoStartInset ? "bit-ash-nis" : string.Empty); + ClassBuilder.Register(() => NoEndInset ? "bit-ash-nie" : string.Empty); } protected override void RegisterCssStyles() @@ -89,14 +614,91 @@ protected override void RegisterCssStyles() StyleBuilder.Register(() => Styles?.Root); } - protected override void OnInitialized() + // The class and the style of the main container, which is the element that actually scrolls - so + // everything about the scrolling of the app shell lands here rather than on the root. + private string _MainClass => string.Join(' ', new[] + { + "bit-ash-main", + // Smooth is the default of the app shell, so the class is on unless another behavior was asked + // for. The stylesheet takes it back off under the reduced motion preference; a behavior handed to + // one of the scrolling methods overrides the property either way, which is why the methods that + // are called without one pass nothing at all and let this property decide. + ScrollBehavior is null or BitScrollBehavior.Smooth ? "bit-ash-smt" : null, + NoScroll ? "bit-ash-nsc" : null, + Classes?.Main + }.Where(c => c.HasValue())); + + private string? _MainStyle { - if (AutoGoToTop || PersistScroll) + get { - _navManager.LocationChanged += LocationChanged; + // Everything the scrolling container is styled with lands in this one attribute, in the order + // the declarations override one another in: whatever the page wrote first, then the ones this + // component derives from its parameters, and NoScroll over all of it - so a shell the reader + // is not to be able to move is never left movable by an overflow the page happened to write. + List declarations = + [ + Styles?.Main?.TrimEnd().TrimEnd(';'), + + Overscroll switch + { + BitOverscroll.Auto => "overscroll-behavior:auto", + BitOverscroll.Contain => "overscroll-behavior:contain", + BitOverscroll.None => "overscroll-behavior:none", + _ => null + }, + + // Each axis is spelled out as its own longhand rather than folded into the shorthand, + // which would also reset the axis it was not asked about. + OverflowX switch + { + BitOverflow.Auto => "overflow-x:auto", + BitOverflow.Hidden => "overflow-x:hidden", + BitOverflow.Scroll => "overflow-x:scroll", + BitOverflow.Visible => "overflow-x:visible", + _ => null + }, + + OverflowY switch + { + BitOverflow.Auto => "overflow-y:auto", + BitOverflow.Hidden => "overflow-y:hidden", + BitOverflow.Scroll => "overflow-y:scroll", + BitOverflow.Visible => "overflow-y:visible", + _ => null + }, + + // Auto is the initial value, which the container already has. + Gutter switch + { + BitScrollbarGutter.Stable => "scrollbar-gutter:stable", + BitScrollbarGutter.BothEdges => "scrollbar-gutter:stable both-edges", + _ => null + }, + + ScrollPadding.HasValue() ? $"scroll-padding:{ScrollPadding}" : null, + + // The class of the container says this as well, but a style attribute wins over a class: + // an overflow written into Styles.Main, or an axis asked for above, would otherwise leave + // the container scrollable after all. + NoScroll ? "overflow:hidden" : null, + ]; + + // Two declarations landing in the same style attribute are only two declarations while a + // semicolon stands between them. + var style = string.Join(';', declarations.Where(d => d.HasValue())); + + return style.HasValue() ? style : null; } + } + + protected override void OnParametersSet() + { + // The two navigation features are parameters like any other, so turning either of them on after + // the shell has been rendered has to subscribe it - and turning both of them off, unsubscribe it. + UpdateSubscription(); - base.OnInitialized(); + base.OnParametersSet(); } protected override async Task OnAfterRenderAsync(bool firstRender) @@ -111,36 +713,306 @@ protected override async Task OnAfterRenderAsync(bool firstRender) StateHasChanged(); } - if (firstRender && PersistScroll) - { - if (_containerRef.HasValue is false) return; + await SetupPersistScroll(); - await _js.BitAppShellInitScroll(_containerRef.Value, _navManager.Uri); - } + await SetupScrollReporting(); + + await SetupKeyboard(); if (_locationChanged && firstRender is false) { _locationChanged = false; - await _js.BitAppShellAfterRenderScroll(_navManager.Uri); + await InvokeJs(() => _js.BitAppShellAfterRenderScroll(_navManager.Uri)); } + + await base.OnAfterRenderAsync(firstRender); } - private void LocationChanged(object? sender, LocationChangedEventArgs args) + // The scroll persistence of the browser side, followed as the parameter flips rather than settled on + // the first render: turning it on later starts it, and turning it off again stops it rather than + // leaving a listener behind that goes on writing positions nothing will ever restore. + private async Task SetupPersistScroll() { + if (PersistScroll == _scrollInit) return; + if (PersistScroll) { - if (IsRendered) + if (_containerRef.HasValue is false) return; + + _scrollInit = true; + + await InvokeJs(() => _js.BitAppShellInitScroll(_containerRef.Value, _navManager.Uri)); + return; + } + + _scrollInit = false; + _locationChanged = false; + + await InvokeJs(() => _js.BitAppShellDisposeScroll()); + } + + // The keyboard tracking, followed as the parameter flips rather than settled on the first render, so + // that a page which only avoids the keyboard on the screens that have a field on them can turn it on + // and off. It costs two listeners on the visual viewport, which is why it is not simply always on. + private async Task SetupKeyboard() + { + if (AvoidKeyboard == _keyboardSetup) return; + + _keyboardSetup = AvoidKeyboard; + + if (AvoidKeyboard is false) + { + await InvokeJs(() => _js.BitAppShellDisposeKeyboard(UniqueId)); + return; + } + + // The reference is handed over whether or not anything is listening for the measurement, since a + // page that starts listening later would otherwise have to make the shell set its tracking up + // again to be heard; the browser side only calls back when the measurement CHANGES, which is once + // or twice per keyboard rather than per frame. + _dotnetObj ??= DotNetObjectReference.Create(this); + + await InvokeJs(() => _js.BitAppShellSetupKeyboard(UniqueId, RootElement, _dotnetObj)); + } + + // The scroll reporting is driven by the very engine BitScrollablePane uses, so there is not a second + // implementation of measuring, throttling and edge detection in the library. It is only ever set up + // for a shell that asked for one of the reports, since it costs a listener and a measurement per + // frame of every scroll. + private async Task SetupScrollReporting() + { + if (_containerRef.HasValue is false) return; + + var options = BuildPaneOptions(); + + if (options is null) + { + _autoScrolled = false; + + if (_paneSetup is false) return; + + _paneSetup = false; + await InvokeJs(() => _js.BitScrollablePaneDispose(UniqueId)); + return; + } + + if (_paneSetup is false) + { + _paneSetup = true; + _paneOptions = options; + _dotnetObj ??= DotNetObjectReference.Create(this); + + await InvokeJs(() => _js.BitScrollablePaneSetup(UniqueId, _containerRef!.Value, _dotnetObj, options)); + } + else if (options != _paneOptions) + { + // Nothing is sent for a set of options the browser side already has, so a shell that + // re-renders on every navigation does not re-configure its scroller on every navigation. + _paneOptions = options; + await InvokeJs(() => _js.BitScrollablePaneUpdate(UniqueId, options)); + } + + // The first pinning is the one this side has to ask for: it is unconditional - a shell that starts + // out with content already in it belongs at the end of it - and the browser side has nothing to + // compare against on its very first measurement, so it would leave a shell that has not scrolled + // yet standing at the top. Every pinning after that is its own answer to the content it watches, + // without a round trip per render. + if (AutoScroll) + { + if (_autoScrolled is false) { - _locationChanged = true; - _ = _js.BitAppShellLocationChangedScroll(_navManager.Uri); + _autoScrolled = true; + + await InvokeJs(() => _js.BitScrollablePaneAutoScroll(UniqueId, true)); } } + else + { + _autoScrolled = false; + } + } + + // What the browser side is driven with, or null when nothing has been asked of it at all. NoScroll is + // passed along because the engine has to know not to move a container whose page alone decides where + // it stands, but it is not on its own a reason to start one: the reader's own scrolling is already + // stopped by `overflow: hidden` in the stylesheet, and the gestures that flag holds the engine back + // from - drag, wheel, momentum - are not ones the shell ever turns on. + private BitScrollablePaneOptions? BuildPaneOptions() + { + var scroll = OnScroll.HasDelegate; + var scrollStart = OnScrollStart.HasDelegate; + var scrollEnd = OnScrollEnd.HasDelegate; + var top = OnReachedTop.HasDelegate; + var bottom = OnReachedBottom.HasDelegate; + var left = OnReachedLeft.HasDelegate; + var right = OnReachedRight.HasDelegate; + + if (scroll is false && scrollStart is false && scrollEnd is false && + top is false && bottom is false && left is false && right is false && + AutoScroll is false && PreserveScroll is false) return null; + + return new() + { + Scroll = scroll, + ScrollStart = scrollStart, + ScrollEnd = scrollEnd, + Top = top, + Bottom = bottom, + Left = left, + Right = right, + Offset = ReachOffset, + Throttle = ScrollThrottle, + NoScroll = NoScroll, + AutoScroll = AutoScroll, + AutoScrollThreshold = AutoScrollThreshold, + Preserve = PreserveScroll, + Smooth = ScrollBehavior is null or BitScrollBehavior.Smooth, + }; + } + + private void UpdateSubscription() + { + var needed = AutoGoToTop || PersistScroll; + + if (needed == _subscribed) return; + + _subscribed = needed; + + if (needed) + { + // Where the application stands as the subscription is taken, so that the FIRST navigation + // after it can be told apart from an in-page anchor as well as every one after that. + _lastLocation = _navManager.Uri; + + _navManager.LocationChanged += LocationChanged; + } + else + { + _navManager.LocationChanged -= LocationChanged; + } + } + + private void LocationChanged(object? sender, LocationChangedEventArgs args) + { + // An in-page anchor is a navigation like any other as far as the NavigationManager is concerned, + // and both features below would fight what following an anchor is asking for: one sends the + // reader to the top of the page they just jumped into, the other to whatever position was stored + // for a url key that has never been scrolled. + if (TakeLocation(args.Location) is false) return; + + if (PersistScroll) + { + if (IsRendered is false) return; + + _locationChanged = true; + + _ = InvokeJs(() => _js.BitAppShellLocationChangedScroll()); + + // The restore happens on the next render of this component. In its intended place - the + // layout - the new page arrives as this component's own ChildContent, so that render is + // guaranteed; asking for it here is what makes the restore work for a shell rendered anywhere + // else too, instead of leaving its browser side with the scroll listener detached. + // Through the dispatcher, since a navigation is not always raised on the renderer's thread - + // a NavigateTo from a background task is not - and a render queued from another one throws. + _ = InvokeAsync(StateHasChanged); + } else if (AutoGoToTop) { - _ = GoToTop(BitScrollBehavior.Instant); + _ = GoToTop(ScrollBehavior ?? BitScrollBehavior.Instant); + } + } + + // Remembers where the application now stands and answers whether that was a navigation to another + // PAGE, which is the only kind either feature above acts on. A move that left everything but the + // fragment of the url the same is an in-page anchor, and both of them would fight what following one + // is asking for. The url the NavigationManager reports is absolute, so the two are compared with the + // fragment cut off each of them. + private bool TakeLocation(string location) + { + var previous = _lastLocation; + + _lastLocation = location; + + if (previous is null) return true; + + if (string.Equals(previous, location, StringComparison.Ordinal)) return true; + + return string.Equals(WithoutFragment(previous), WithoutFragment(location), StringComparison.Ordinal) is false; + } + + private static string WithoutFragment(string url) + { + var index = url.IndexOf('#', StringComparison.Ordinal); + + return index < 0 ? url : url[..index]; + } + + // Every call out to the browser goes through here, so that the two failures none of them can do + // anything about - a circuit that dropped, and a runtime already torn down - are never surfaced as an + // unhandled exception of an application that did nothing wrong. + private async Task InvokeJs(Func action) + { + try + { + await action(); } + catch (JSDisconnectedException) { } + catch (ObjectDisposedException) { } + } + + + + [JSInvokable("OnScroll")] + public async Task _OnScroll(BitScrollOffset offset) + { + if (IsDisposed || offset is null) return; + + await OnScroll.InvokeAsync(offset); + } + + [JSInvokable("OnScrollStart")] + public async Task _OnScrollStart(BitScrollOffset offset) + { + if (IsDisposed || offset is null) return; + + await OnScrollStart.InvokeAsync(offset); + } + + [JSInvokable("OnScrollEnd")] + public async Task _OnScrollEnd(BitScrollOffset offset) + { + if (IsDisposed || offset is null) return; + + await OnScrollEnd.InvokeAsync(offset); + } + + [JSInvokable("OnReached")] + public async Task _OnReached(string edge) + { + if (IsDisposed) return; + + var callback = edge switch + { + "top" => OnReachedTop, + "bottom" => OnReachedBottom, + "left" => OnReachedLeft, + "right" => OnReachedRight, + _ => default + }; + + if (callback.HasDelegate is false) return; + + await callback.InvokeAsync(); + } + + [JSInvokable("OnKeyboardInset")] + public async Task _OnKeyboardInset(double inset) + { + if (IsDisposed || OnKeyboardInsetChanged.HasDelegate is false) return; + + await OnKeyboardInsetChanged.InvokeAsync(inset); } @@ -150,16 +1022,26 @@ protected override async ValueTask DisposeAsync(bool disposing) if (IsDisposed || disposing is false) return; _navManager.LocationChanged -= LocationChanged; + _subscribed = false; - if (PersistScroll) + if (_scrollInit) { - try - { - await _js.BitAppShellDisposeScroll(); - } - catch (JSDisconnectedException) { } // we can ignore this exception here + await InvokeJs(() => _js.BitAppShellDisposeScroll()); + } + + if (_paneSetup) + { + await InvokeJs(() => _js.BitScrollablePaneDispose(UniqueId)); } + if (_keyboardSetup) + { + await InvokeJs(() => _js.BitAppShellDisposeKeyboard(UniqueId)); + } + + _dotnetObj?.Dispose(); + _dotnetObj = null; + await base.DisposeAsync(disposing); } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.scss index f9aa459c37..b20aeaf7bb 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.scss @@ -1,7 +1,33 @@ @import '../../Styles/extra-variables.scss'; @import '../../../Bit.BlazorUI/Styles/functions.scss'; +// Deliberately outside the library's z-index scale (which tops out at the snackbar's 1400). The four +// bars mask the physical chrome of the device - the notch, the rounded corners, the home indicator - so +// there is nothing an application can render that is allowed to paint over them. +$bit-ash-inset-zindex: 999999; + +// The four bars around the main container are sized from custom properties of their own rather than +// straight off the env() values, so that NoInsets has one place to take all four back to zero and a page +// can override a single edge without having to know how the bar is built. +// The two side ones read the LOGICAL insets: the center is laid out in the reading direction, so its +// first child is the physically right one in a right-to-left app shell - and the physical right edge is +// the one whose inset it has to be sized by. .bit-ash { + --bit-ash-inset-top: #{$bit-env-inset-top}; + --bit-ash-inset-bottom: #{$bit-env-inset-bottom}; + --bit-ash-inset-start: #{$bit-env-inset-inline-start}; + --bit-ash-inset-end: #{$bit-env-inset-inline-end}; + // How much of the shell the on-screen keyboard is covering. It stays 0 unless AvoidKeyboard is set, + // which is what puts the measured height here from the browser side; a page can read it to place + // chrome of its own against the same number. + --bit-ash-keyboard-inset: 0px; + // How much of the bottom inset is still worth keeping while the keyboard is open. The inset is there + // to keep content off the home indicator, and the keyboard is already covering everything that far up + // the screen - so a bar of the shell's background left below the content and above the keyboard is + // room taken from the content for nothing at all. What the keyboard has taken over is taken off here, + // and the middle below is sized from this rather than from the inset itself. + --bit-ash-inset-bottom-visible: max(0px, calc(var(--bit-ash-inset-bottom) - var(--bit-ash-keyboard-inset))); + width: 100%; height: 100%; display: flex; @@ -9,24 +35,71 @@ background-color: $clr-bg-pri; } +// The insets a browser reports change while its own retractable UI slides in and out - the bottom bar of +// an edge-to-edge Chrome on Android does it on every scroll - which moves the two bars sized from them on +// every frame of that slide. Asked for stable insets, the shell is sized from the STATIC maximums of the +// same four instead: the layout is laid out once, for the room left when nothing is retracted, and the +// browser slides its UI over the background of a bar rather than over the content. +.bit-ash-sin { + --bit-ash-inset-top: #{$bit-env-max-inset-top}; + --bit-ash-inset-bottom: #{$bit-env-max-inset-bottom}; + --bit-ash-inset-start: #{$bit-env-max-inset-inline-start}; + --bit-ash-inset-end: #{$bit-env-max-inset-inline-end}; +} + +.bit-ash-nin { + --bit-ash-inset-top: 0px; + --bit-ash-inset-bottom: 0px; + --bit-ash-inset-start: 0px; + --bit-ash-inset-end: 0px; +} + +// And one edge at a time, for the application that insets that edge itself. These come after both rules +// above, so an edge taken away stays away whether the shell was asked for stable insets or for none: a +// shell asking for both has asked for one edge to be gone, and the other three to be sized either way. +.bit-ash-nit { + --bit-ash-inset-top: 0px; +} + +.bit-ash-nib { + --bit-ash-inset-bottom: 0px; +} + +.bit-ash-nis { + --bit-ash-inset-start: 0px; +} + +.bit-ash-nie { + --bit-ash-inset-end: 0px; +} + +// The shell of an application owns the window: nothing is laid out around it and nothing is scrolled +// past it, so it can be positioned against the viewport rather than sized by whatever room the page gives +// it - which is what saves the host page from having to carry a height of its own down through html and +// body. The height above resolves against the viewport here, so both ways of asking agree. +.bit-ash-fsc { + inset: 0; + position: fixed; +} + .bit-ash-top { width: 100%; - z-index: 999999; - height: $bit-env-inset-top; + z-index: $bit-ash-inset-zindex; + height: var(--bit-ash-inset-top); background-color: $clr-bg-pri; } .bit-ash-bottom { width: 100%; - z-index: 999999; - height: $bit-env-inset-bottom; + z-index: $bit-ash-inset-zindex; + height: var(--bit-ash-inset-bottom-visible); background-color: $clr-bg-pri; } .bit-ash-center { width: 100%; display: flex; - height: calc(100% - $bit-env-inset-top - $bit-env-inset-bottom); + height: calc(100% - var(--bit-ash-inset-top) - var(--bit-ash-inset-bottom-visible) - var(--bit-ash-keyboard-inset)); } .bit-ash-main { @@ -34,21 +107,40 @@ display: flex; overflow: auto; position: relative; - scroll-behavior: smooth; overscroll-behavior: none; - width: calc(100% - $bit-env-inset-left - $bit-env-inset-right); + width: calc(100% - var(--bit-ash-inset-start) - var(--bit-ash-inset-end)); +} + +// Applies to every move the main container is not dragged to by the reader: the scrolling API of the +// component, a fragment navigation into it, and the browser bringing a focused element into view. +.bit-ash-smt { + scroll-behavior: smooth; +} + +// The force-animation class opts a whole SUBTREE out of the preference, so a shell carrying it keeps its +// smooth scrolling - which is what every other animated component in the library does with it. +@media (prefers-reduced-motion: reduce) { + .bit-ash-smt:not(.bit-fam):not(.bit-fam *) { + scroll-behavior: auto; + } +} + +// Only the reader's own gestures are stopped. The element stays scrollable through the scrolling API, +// which is what the public methods of the component move it with. +.bit-ash-nsc { + overflow: hidden; } .bit-ash-left { height: 100%; - z-index: 999999; - width: $bit-env-inset-left; + z-index: $bit-ash-inset-zindex; + width: var(--bit-ash-inset-start); background-color: $clr-bg-pri; } .bit-ash-right { height: 100%; - z-index: 999999; - width: $bit-env-inset-right; + z-index: $bit-ash-inset-zindex; + width: var(--bit-ash-inset-end); background-color: $clr-bg-pri; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.ts b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.ts index dc2e83e512..da7feb325c 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.ts +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.ts @@ -2,40 +2,113 @@ namespace BitBlazorUI { export class AppShell { private static STORE_KEY = 'bit-appshell-scrolls'; + // How many positions are kept. The map is one JSON blob in session storage, so an app that is + // navigated around for an hour would otherwise carry every url it has ever shown into every + // write. The oldest entries are the ones dropped, which is what the insertion order of the object + // gives for free: a url that is visited again is re-inserted at the end by touch(). + private static STORE_MAX = 100; + public static PreScroll: number = 0; private static _currentUrl: string; private static _container: HTMLElement | undefined; private static _scrolls: { [key: string]: number | undefined } = {}; + // The frame a pending store is waiting on, and whether anything has changed since the last one was + // written. A scroll fires many times per gesture and each write is a JSON.stringify plus a + // synchronous session storage write, so the position is only ever written once per animation frame + // - and the final position of a gesture is caught by the flush listeners below, which run even + // when the page is being torn down before that frame ever arrives. + private static _frame = 0; + private static _dirty = false; + + private static _flushBound = false; + + // How long a restore keeps trying to reach a position the content is not tall enough for yet, and + // what it is trying to reach: -1 while nothing is being restored, which is also what tells the + // scroll listener that the moves it is seeing are the reader's own. + private static RESTORE_WINDOW = 2000; + private static _restoreTop = -1; + private static _restoreEnd = 0; + private static _restoreFrame = 0; + private static _restoreEvents = ['wheel', 'touchstart', 'pointerdown', 'keydown']; + public static initScroll(container: HTMLElement, url: string) { AppShell._container = container; AppShell._currentUrl = url; - AppShell._scrolls = JSON.parse(sessionStorage.getItem(AppShell.STORE_KEY) || '{}'); + AppShell._scrolls = AppShell.read(); AppShell.storeScroll(url, AppShell.PreScroll > 0 ? AppShell.PreScroll : AppShell._scrolls[url]); + // Spent. It is where the reader had got to on the shell the SERVER rendered, so it only ever + // belongs to the first url of the session; a shell whose persistence is turned on again later + // would otherwise be handed a position from a page it has long since navigated away from. + AppShell.PreScroll = 0; + // A page opened at a position of 0 is left exactly where it is rather than being sent to the + // top: the browser may already have scrolled the container to the fragment of the url it was + // opened at, and a restore of a position nobody ever stored would undo it. if (AppShell._scrolls[url]! > 0) { - AppShell._container.scrollTo({ top: AppShell._scrolls[url], behavior: 'instant' }); + AppShell.restore(AppShell._scrolls[url]); } AppShell.addScroll(); + AppShell.bindFlush(); } - public static locationChangedScroll(url: string) { + public static locationChangedScroll() { + // Whatever was being restored belongs to the page being left. + AppShell.cancelRestore(); + // The position of the page being left is written out now rather than being left to the frame + // a pending store is waiting on: the next thing to happen is a render of the new page, and a + // scroll of the container to the new page's position would be read by that pending store as + // the position of the OLD url. + AppShell.flush(); AppShell.removeScroll(); } public static afterRenderScroll(url: string) { AppShell._currentUrl = url; AppShell.storeScroll(url, AppShell._scrolls[url]); - AppShell._container?.scrollTo({ top: AppShell._scrolls[url], behavior: 'instant' }); + // As in initScroll: a page with nothing stored, or stored at 0, is left where the browser has + // already put it - which is the fragment of the url it was navigated to, if it had one. + if (AppShell._scrolls[url]! > 0) { + AppShell.restore(AppShell._scrolls[url]); + } AppShell.addScroll(); } public static disposeScroll() { + AppShell.cancelRestore(); + AppShell.flush(); AppShell.removeScroll(); + AppShell.unbindFlush(); + AppShell._container = undefined; + } + + // Empties the stored positions, both the ones in hand and the ones in session storage, so that an + // application that signs a user out does not restore the previous one's place in the pages the + // next one visits. Given a url, only that page is forgotten - a page whose content has been + // replaced under the reader is no longer at the position it was left at. + public static clearScrolls(url?: string) { + AppShell.cancelRestore(); + + if (url) { + delete AppShell._scrolls[url]; + AppShell._dirty = true; + AppShell.flush(); + return; + } + + AppShell._scrolls = {}; + AppShell.cancelFrame(); + AppShell._dirty = false; + + try { + window.sessionStorage.removeItem(AppShell.STORE_KEY); + } catch { /* storage unavailable; the in-memory map is cleared either way */ } } private static addScroll() { - AppShell._container?.addEventListener('scroll', AppShell.onScroll); + // Passive: nothing here ever prevents the scroll, and saying so keeps the browser from waiting + // on this listener before it paints the next frame of the app's primary scroller. + AppShell._container?.addEventListener('scroll', AppShell.onScroll, { passive: true }); } private static removeScroll() { @@ -43,21 +116,340 @@ namespace BitBlazorUI { } private static onScroll() { + // A move this class is making itself is not the reader's place to keep. Without this the + // scroll event of a restore that the content was not tall enough for yet would store the + // position it was CLAMPED to, and the place being restored to would be lost on the way to it. + if (AppShell._restoreTop >= 0) return; + AppShell.storeScroll(AppShell._currentUrl, AppShell._container?.scrollTop); } + // Puts the container back where the url was left. The content of a page being returned to is + // rarely as tall as it will be by the time it has finished arriving - a fetch still in flight, an + // image without a size in its markup, a virtualized list that has only rendered its first screen - + // and a container that is not tall enough yet clamps the move to wherever it can reach. So the + // move is repeated as the content grows, until it lands or until the window below is spent. + private static restore(top: number | undefined) { + AppShell.cancelRestore(); + + const container = AppShell._container; + if (!container) return; + + const target = Math.max(0, top || 0); + + container.scrollTo({ top: target, behavior: 'instant' }); + + // The top of the content is where a page that was never scrolled opens, and it is reachable + // however short the content is, so there is nothing to wait for. + if (target === 0) return; + + AppShell._restoreTop = target; + AppShell._restoreEnd = AppShell.now() + AppShell.RESTORE_WINDOW; + AppShell.bindRestoreCancel(); + AppShell._restoreFrame = requestAnimationFrame(AppShell.restoreStep); + } + + private static restoreStep() { + AppShell._restoreFrame = 0; + + const container = AppShell._container; + const target = AppShell._restoreTop; + if (!container || target < 0) return; + + const max = Math.max(0, container.scrollHeight - container.clientHeight); + const reachable = Math.min(target, max); + + if (Math.abs(container.scrollTop - reachable) > 1) { + container.scrollTo({ top: target, behavior: 'instant' }); + } + + // Landed, or out of time. Either way what was stored for this url is left as it was, so a + // page whose content never grew that far is still put back there the next time it is opened. + if (max >= target - 1 || AppShell.now() >= AppShell._restoreEnd) { + AppShell.cancelRestore(); + return; + } + + AppShell._restoreFrame = requestAnimationFrame(AppShell.restoreStep); + } + + private static cancelRestore() { + if (AppShell._restoreFrame) { + cancelAnimationFrame(AppShell._restoreFrame); + AppShell._restoreFrame = 0; + } + + AppShell._restoreTop = -1; + AppShell.unbindRestoreCancel(); + } + + // Being put back where they left off is worth nothing to a reader who is already going somewhere + // else, so the first thing they do gives up on the restore. The four events are the ways a scroll + // is asked for that are not this class asking for it; the scroll event itself is not one of them, + // since every move the restore makes raises one. + private static bindRestoreCancel() { + AppShell._restoreEvents.forEach(e => + window.addEventListener(e, AppShell.cancelRestore, { passive: true, capture: true })); + } + + private static unbindRestoreCancel() { + AppShell._restoreEvents.forEach(e => + window.removeEventListener(e, AppShell.cancelRestore, { capture: true } as any)); + } + + private static now(): number { + try { + return performance.now(); + } catch { + return Date.now(); + } + } + private static storeScroll(url: string, value: number | undefined) { + if (!url) return; + + const known = url in AppShell._scrolls; + AppShell._scrolls[url] = value || 0; - window.sessionStorage.setItem(AppShell.STORE_KEY, JSON.stringify(AppShell._scrolls)); + + // A url already at the end of the order is where touch() would put it, and the cap was + // enforced when it got there - so the scrolling of one page, which stores a position per + // frame, does not re-key the map and walk its keys for every one of them. + if (known === false || AppShell._mru !== url) { + AppShell.touch(url); + } + + AppShell.schedule(); + } + + // The url at the end of the insertion order, so a repeated store of the same page can tell that + // there is nothing to move. + private static _mru: string | undefined; + + // Moves a url to the end of the insertion order and drops whatever falls out of the cap, so the + // map stays bounded by the pages most recently looked at rather than by every page ever visited. + private static touch(url: string) { + AppShell._mru = url; + + const value = AppShell._scrolls[url]; + delete AppShell._scrolls[url]; + AppShell._scrolls[url] = value; + + const keys = Object.keys(AppShell._scrolls); + for (let i = 0; i < keys.length - AppShell.STORE_MAX; i++) { + delete AppShell._scrolls[keys[i]]; + } + } + + private static schedule() { + AppShell._dirty = true; + + if (AppShell._frame) return; + + AppShell._frame = requestAnimationFrame(() => { + AppShell._frame = 0; + AppShell.write(); + }); + } + + // Writes whatever is pending right now, for the moments there is no next frame to wait for: the + // page being hidden, the tab being closed, the navigation that is about to re-render the shell. + private static flush() { + AppShell.cancelFrame(); + AppShell.write(); + } + + private static cancelFrame() { + if (AppShell._frame === 0) return; + + cancelAnimationFrame(AppShell._frame); + AppShell._frame = 0; + } + + private static write() { + if (AppShell._dirty === false) return; + + AppShell._dirty = false; + + try { + window.sessionStorage.setItem(AppShell.STORE_KEY, JSON.stringify(AppShell._scrolls)); + } catch { /* private mode, disabled storage or a full quota; the positions stay in memory */ } + } + + private static read(): { [key: string]: number | undefined } { + try { + const stored = JSON.parse(sessionStorage.getItem(AppShell.STORE_KEY) || '{}'); + return (stored && typeof stored === 'object') ? stored : {}; + } catch { + // Unavailable storage, or a value another script left behind that is not the map this + // wrote. Either way there is nothing to restore, and starting from an empty map is what + // keeps every write after this one working. + return {}; + } + } + + private static onFlush() { + AppShell.flush(); + } + + private static bindFlush() { + if (AppShell._flushBound) return; + + AppShell._flushBound = true; + + // pagehide is the one teardown notification a mobile browser reliably gives - unload is not + // fired when a tab is discarded or restored from the back/forward cache - and the hidden half + // of visibilitychange covers the app being switched away from without being torn down at all. + window.addEventListener('pagehide', AppShell.onFlush); + document.addEventListener('visibilitychange', AppShell.onFlush); + } + + private static unbindFlush() { + if (AppShell._flushBound === false) return; + + AppShell._flushBound = false; + + window.removeEventListener('pagehide', AppShell.onFlush); + document.removeEventListener('visibilitychange', AppShell.onFlush); + } + + + + // How much of the layout viewport the on-screen keyboard is covering, published on the root of a + // shell as --bit-ash-keyboard-inset so its own stylesheet can take that much off the height of the + // scrolling middle - and so the page can position chrome of its own against the same number. + // + // The visual viewport is the only place this can be read from: opening the keyboard leaves the + // LAYOUT viewport (and therefore every percentage height on the page) exactly as it was on the + // platforms that need this, so a shell measured in percentages goes on believing it owns a screen + // whose bottom is now behind the keyboard. Where the browser does shrink the layout viewport + // instead - a page asking for `interactive-widget=resizes-content`, or a desktop browser - the two + // viewports keep matching and this reports 0, which is the right answer: there is nothing left to + // take off a height that has already been taken off. + private static _keyboards: { [key: string]: { element: HTMLElement, handler: () => void, frame: number, last: number, style: HTMLStyleElement, dotnetObj?: DotNetObject } } = {}; + + public static setupKeyboard(id: string, element: HTMLElement, dotnetObj?: DotNetObject) { + if (!element) return; + + AppShell.disposeKeyboard(id); + + const viewport = window.visualViewport; + if (!viewport) return; + + // The number is published through a stylesheet of this shell's own rather than as an inline + // custom property, because the style attribute of the root is written by Blazor on every + // render that changes it and anything this side had put there would be wiped - after which + // the unchanged-inset check below would never write it again while the keyboard stayed open. + // The shell is addressed by an attribute the renderer never knew about, so nothing removes + // it either, and the class is repeated in the selector to outweigh the 0px the stylesheet + // declares whatever order the two are loaded in. + const style = document.createElement('style'); + document.head.appendChild(style); + element.setAttribute('data-bit-ash-kbd', id); + + const state = { element, handler: () => { }, frame: 0, last: -1, style, dotnetObj }; + + const measure = () => { + state.frame = 0; + + // A pinch-zoomed page shrinks its visual viewport in exactly the way an open keyboard + // does, so measuring through one would report a keyboard that is not there - and taking + // that much off the shell while the reader is zoomed in is the one thing worse than + // ignoring the keyboard. The measurement is left at whatever it was until the zoom is let + // go of, which keeps an open keyboard accounted for through a zoom as well. + if (Math.abs((viewport.scale || 1) - 1) > 0.01) return; + + // The height of the LAYOUT viewport, which is what the keyboard does not shrink on the + // platforms this is for - read off the document element rather than as window.innerHeight + // because that one counts the horizontal scrollbar the visual viewport height leaves out, + // and the difference between the two would be reported as a keyboard of that height. + const layout = document.documentElement?.clientHeight || window.innerHeight; + + // offsetTop is how far the visual viewport has itself been pushed down the layout one, + // which is what a page scrolled by the browser to keep a focused field in view leaves + // behind; without it the keyboard would appear to grow by that much. + const inset = Math.max(0, Math.round(layout - viewport.height - viewport.offsetTop)); + + if (inset === state.last) return; + + state.last = inset; + state.style.textContent = `.bit-ash[data-bit-ash-kbd="${id}"]{--bit-ash-keyboard-inset:${inset}px}`; + + // A marker for the CSS that cannot be written against a length - the bottom bar a shell + // hides while the reader is typing, the map that drops its controls - so a page does not + // have to round-trip through C# to know the keyboard is up. + if (inset > 0) { + state.element.setAttribute('data-bit-ash-keyboard', ''); + } else { + state.element.removeAttribute('data-bit-ash-keyboard'); + } + + // And the same number for the page that has to place something in C# rather than in CSS. + // It is sent on the change rather than per frame, and a failed send is a shell that has + // gone away between the measurement and the call, which is nothing this can act on. + state.dotnetObj?.invokeMethodAsync('OnKeyboardInset', inset).catch(() => { }); + }; + + state.handler = () => { + if (state.frame) return; + state.frame = requestAnimationFrame(measure); + }; + + viewport.addEventListener('resize', state.handler, { passive: true }); + viewport.addEventListener('scroll', state.handler, { passive: true }); + + AppShell._keyboards[id] = state; + + measure(); + } + + public static disposeKeyboard(id: string) { + const state = AppShell._keyboards[id]; + if (!state) return; + + delete AppShell._keyboards[id]; + + if (state.frame) { + cancelAnimationFrame(state.frame); + } + + const viewport = window.visualViewport; + if (viewport) { + viewport.removeEventListener('resize', state.handler); + viewport.removeEventListener('scroll', state.handler); + } + + state.style.remove(); + state.element.removeAttribute('data-bit-ash-kbd'); + state.element.removeAttribute('data-bit-ash-keyboard'); } } } (function () { - const container = document.getElementById('BitAppShell-container'); - if (!container) return; + // The scrolling the reader does before Blazor has started, on the shell rendered by the server. Only + // the FIRST shell of a page can be scrolled at this point, since it is the one in the server's markup + // and a second shell is something only a started application can render. + function bind() { + // The well-known id first, then the attribute every app shell's container carries whatever its id + // is: a shell given an Id of its own derives its container id from that one, and the scrolling + // done before Blazor has started is worth keeping for it too. + const container = document.getElementById('BitAppShell-container') + ?? document.querySelector('[data-bit-ash-main]'); + + if (!container) return false; + + container.addEventListener('scroll', () => { + BitBlazorUI.AppShell.PreScroll = container.scrollTop; + }, { passive: true }); - container.addEventListener('scroll', e => { - BitBlazorUI.AppShell.PreScroll = container.scrollTop; - }); -}()); \ No newline at end of file + return true; + } + + // The script is meant to run after the markup it is looking for, which is where a Blazor host page puts + // it. A page that loads it from the head instead is still served, by looking again once the document + // has been parsed - the scrolling this keeps is the reader's, and it only happens after that anyway. + if (bind() === false && document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => { bind(); }, { once: true }); + } +}()); diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellClassStyles.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellClassStyles.cs index 703b86ce31..dc82324351 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellClassStyles.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellClassStyles.cs @@ -18,17 +18,20 @@ public class BitAppShellClassStyles public string? Center { get; set; } /// - /// Custom CSS classes/styles for the left area of the BitAppShell. + /// Custom CSS classes/styles for the leading side inset bar of the BitAppShell, which is the one on + /// the left of a left-to-right app shell and on the right of a right-to-left one. /// public string? Left { get; set; } /// - /// Custom CSS classes/styles for the main area of the BitAppShell. + /// Custom CSS classes/styles for the main container of the BitAppShell, which is the one part of it + /// that scrolls and the one the content is rendered into. /// public string? Main { get; set; } /// - /// Custom CSS classes/styles for the right area of the BitAppShell. + /// Custom CSS classes/styles for the trailing side inset bar of the BitAppShell, which is the one on + /// the right of a left-to-right app shell and on the left of a right-to-left one. /// public string? Right { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellJsRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellJsRuntimeExtensions.cs index 6b9bf75064..a217507dd9 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellJsRuntimeExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellJsRuntimeExtensions.cs @@ -1,6 +1,4 @@ -using System.ComponentModel; - -namespace Bit.BlazorUI; +namespace Bit.BlazorUI; internal static class BitAppShellJsRuntimeExtensions { @@ -9,9 +7,9 @@ internal static ValueTask BitAppShellInitScroll(this IJSRuntime jsRuntime, Eleme return jsRuntime.InvokeVoid("BitBlazorUI.AppShell.initScroll", container, url); } - internal static ValueTask BitAppShellLocationChangedScroll(this IJSRuntime jsRuntime, string url) + internal static ValueTask BitAppShellLocationChangedScroll(this IJSRuntime jsRuntime) { - return jsRuntime.InvokeVoid("BitBlazorUI.AppShell.locationChangedScroll", url); + return jsRuntime.InvokeVoid("BitBlazorUI.AppShell.locationChangedScroll"); } internal static ValueTask BitAppShellAfterRenderScroll(this IJSRuntime jsRuntime, string url) @@ -23,4 +21,22 @@ internal static ValueTask BitAppShellDisposeScroll(this IJSRuntime jsRuntime) { return jsRuntime.InvokeVoid("BitBlazorUI.AppShell.disposeScroll"); } + + internal static ValueTask BitAppShellClearScrolls(this IJSRuntime jsRuntime, string? url = null) + { + return jsRuntime.InvokeVoid("BitBlazorUI.AppShell.clearScrolls", url); + } + + internal static ValueTask BitAppShellSetupKeyboard(this IJSRuntime jsRuntime, + string id, + ElementReference element, + DotNetObjectReference dotnetObj) where T : class + { + return jsRuntime.InvokeVoid("BitBlazorUI.AppShell.setupKeyboard", id, element, dotnetObj); + } + + internal static ValueTask BitAppShellDisposeKeyboard(this IJSRuntime jsRuntime, string id) + { + return jsRuntime.InvokeVoid("BitBlazorUI.AppShell.disposeKeyboard", id); + } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.Export.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.Export.cs new file mode 100644 index 0000000000..91746d7eb9 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.Export.cs @@ -0,0 +1,172 @@ +using System.Globalization; +using System.Text; + +namespace Bit.BlazorUI; + +/// +/// Export helpers. The chart is already a live SVG element, so exporting is a matter of serializing it +/// (SVG), rasterizing that serialization (PNG), or writing the underlying values out (CSV). +/// +public partial class BitChart +{ + /// + /// Downloads the chart as a standalone .svg file. The theme tokens the chart references are + /// resolved into the exported file so it looks the same outside the app. + /// + /// File name to save as; defaults to chart.svg. + /// Optional background painted behind the chart (SVG is transparent by default). + /// True when the file was produced. + public async Task ExportSvgAsync(string? fileName = null, string? backgroundColor = null) + { + try + { + return await JS.BitChartExportSvg(_plotEl, fileName ?? "chart.svg", backgroundColor); + } + catch + { + return false; + } + } + + /// + /// Downloads the chart as a .png image, rasterized from the live SVG. + /// + /// File name to save as; defaults to chart.png. + /// Pixel ratio; 2 (the default) produces a crisp image on high-density displays. + /// Background painted behind the chart; PNG is transparent without it. + /// True when the file was produced. + public async Task ExportPngAsync(string? fileName = null, double scale = 2, string? backgroundColor = "#ffffff") + { + try + { + return await JS.BitChartExportPng(_plotEl, fileName ?? "chart.png", scale <= 0 ? 1 : scale, backgroundColor); + } + catch + { + return false; + } + } + + /// + /// Returns the chart as standalone SVG markup instead of downloading it - for embedding it in a + /// report, mailing it, or storing it - with the theme tokens it references resolved into the markup + /// so it looks the same outside the app. + /// + /// Optional background painted behind the chart (SVG is transparent by default). + /// The SVG markup, or null when the chart has not been rendered in a browser yet. + public async Task ToSvgStringAsync(string? backgroundColor = null) + { + try + { + return await JS.BitChartToSvgString(_plotEl, backgroundColor); + } + catch + { + return null; + } + } + + /// + /// Returns the chart as a rasterized data: URL - the same picture + /// downloads - ready to drop into an img src or a PDF. Mirrors Chart.js's toBase64Image. + /// + /// Image type to encode; image/png by default (image/jpeg and image/webp also work). + /// Pixel ratio; 2 (the default) produces a crisp image on high-density displays. + /// Background painted behind the chart; PNG is transparent without it. + /// The data URL, or null when the chart has not been rendered in a browser yet. + public async Task ToBase64ImageAsync(string mimeType = "image/png", double scale = 2, + string? backgroundColor = "#ffffff") + { + try + { + return await JS.BitChartToDataUrl(_plotEl, mimeType, scale <= 0 ? 1 : scale, backgroundColor); + } + catch + { + return null; + } + } + + /// Downloads the chart's data as a .csv file. + /// File name to save as; defaults to chart.csv. + /// True when the file was produced. + public async Task ExportCsvAsync(string? fileName = null) + { + try + { + await JS.BitChartDownloadText(fileName ?? "chart.csv", ToCsv(), "text/csv;charset=utf-8"); + return true; + } + catch + { + return false; + } + } + + /// + /// Renders the chart's data as CSV. Value datasets become one row per series with a column per + /// label; point datasets (scatter/bubble) become one row per point. + /// + public string ToCsv() + { + var data = _config.Data; + var culture = Culture; + var sb = new StringBuilder(); + + if (HasPointData) + { + sb.AppendLine("Series,X,Y,R"); + foreach (var ds in data.Datasets) + { + if (ds.Points is not { } pts) continue; + foreach (var p in pts) + sb.Append(CsvText(ds.Label ?? "Series")).Append(',') + .Append(Csv(p.X.ToString(culture))).Append(',') + .Append(Csv(p.Y.ToString(culture))).Append(',') + .AppendLine(p.R is { } r ? Csv(r.ToString(culture)) : ""); + } + return sb.ToString(); + } + + sb.Append("Series"); + foreach (var label in data.Labels) sb.Append(',').Append(CsvText(label)); + sb.AppendLine(); + + foreach (var ds in data.Datasets) + { + sb.Append(CsvText(ds.Label ?? "Series")); + if (ds.RangeData is { } ranges) + { + foreach (var r in ranges) + sb.Append(',').Append(r is { } rr ? Csv($"{rr.Low.ToString(culture)} - {rr.High.ToString(culture)}") : ""); + } + else + { + foreach (var v in ds.Data) + sb.Append(',').Append(v is { } vv ? Csv(vv.ToString(culture)) : ""); + } + sb.AppendLine(); + } + return sb.ToString(); + } + + /// + /// Quotes a caller-supplied text field - a series or category label - and neutralizes the leading + /// characters a spreadsheet reads as the start of a formula, so a label taken from user data cannot + /// become executable content when the file is opened. Formatted numbers keep going through + /// , where a leading minus sign is a sign rather than an injection. + /// + private static string CsvText(string value) + { + if (value.Length > 0 && value[0] is '=' or '+' or '-' or '@' or '\t' or '\r') + value = "'" + value; + return Csv(value); + } + + /// Quotes a CSV field when it contains a separator, quote or newline. + private static string Csv(string value) + { + if (value.IndexOfAny([',', '"', '\n', '\r']) < 0) return value; + return '"' + value.Replace("\"", "\"\"") + '"'; + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor index ba420897c3..21d4594327 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor @@ -1,19 +1,13 @@ @namespace Bit.BlazorUI -
- @((MarkupString)AnimationStyles) - @if (RespectReducedMotion) +
+ @if (_scene.Title is { } title && TitleSide(title) == BitChartPosition.Top) { - @((MarkupString)ReducedMotionStyles) + @RenderTitle(title, "bit-cht-ttl") } - - @if (_scene.Title is { Position: not BitChartPosition.Bottom } title) - { - @RenderTitle(title, "bc-title") - } - @if (_scene.Subtitle is { Position: not BitChartPosition.Bottom } sub) + @if (_scene.Subtitle is { } sub && TitleSide(sub) == BitChartPosition.Top) { - @RenderTitle(sub, "bc-subtitle") + @RenderTitle(sub, "bit-cht-sub") } @if (_scene.Legend is { Position: BitChartPosition.Top }) @@ -21,14 +15,22 @@ @RenderLegend(_scene.Legend) } -
+
+ @if (_scene.Title is { } leftTitle && TitleSide(leftTitle) == BitChartPosition.Left) + { + @RenderTitle(leftTitle, "bit-cht-ttl bit-cht-ttl-v") + } @if (_scene.Legend is { Position: BitChartPosition.Left }) { @RenderLegend(_scene.Legend) } -
- +
+ @if (_scene.PlotArea is { } pa) { @@ -64,12 +66,27 @@ @RenderPattern(pat) } - + @foreach (var n in _scene.Background) { } + @* Invisible per-index hit areas. They sit below the data so an element under the + pointer always wins, and make the chart hoverable across the whole plot. The + pointerdown handler is what gives a touch screen - which never hovers - the same + tooltip on a tap. *@ + + @foreach (var band in _scene.HitBands) + { + + } + @foreach (var n in _scene.Series) { @@ -82,6 +99,7 @@ var el = _scene.Elements[ei]; @if (el.BorderShape is { } bs) @@ -91,7 +109,7 @@ } - + @foreach (var n in _hoverNodes) { @@ -99,10 +117,10 @@ @if (_dragBox is { } db) { + fill="@_config.Options.Zoom.DragBoxColor" stroke="@_config.Options.Zoom.DragBoxBorderColor" stroke-width="1" /> } - + @foreach (var n in _scene.Foreground) { @@ -110,40 +128,55 @@ + @if (_scene.IsEmpty) + { +
+ @if (NoDataTemplate is not null) + { + @NoDataTemplate + } + else + { + @NoDataText + } +
+ } + @if (_activeTooltip is { } tt && _config.Options.Plugins.Tooltip.Enabled) { var t = _config.Options.Plugins.Tooltip; + var pos = TooltipPlacement(tt); @if (TooltipTemplate is not null && _tooltipContext is { } ctx) { -
+
@TooltipTemplate(ctx)
} else { -
+
@if (!string.IsNullOrEmpty(tt.Title)) { -
@tt.Title
+
@tt.Title
} @foreach (var line in tt.BeforeBody) { -
@line
+
@line
} @foreach (var item in tt.Items) { -
+
@if (t.DisplayColors) { @if (t.UsePointStyle && item.PointStyle is { } ps && BitChartPointShapes.Build(ps, 7, 7, 5, item.Color, item.Color, 1) is { } marker) { - + } } @item.Text @@ -151,17 +184,21 @@ } @foreach (var line in tt.AfterBody) { -
@line
+
@line
} @if (tt.Footer.Count > 0) { - } } @@ -171,6 +208,10 @@ { @RenderLegend(_scene.Legend) } + @if (_scene.Title is { } rightTitle && TitleSide(rightTitle) == BitChartPosition.Right) + { + @RenderTitle(rightTitle, "bit-cht-ttl bit-cht-ttl-v") + }
@if (_scene.Legend is { Position: BitChartPosition.Bottom }) @@ -178,13 +219,18 @@ @RenderLegend(_scene.Legend) } - @if (_scene.Subtitle is { Position: BitChartPosition.Bottom } subBottom) + @if (_scene.Subtitle is { } subBottom && TitleSide(subBottom) == BitChartPosition.Bottom) + { + @RenderTitle(subBottom, "bit-cht-sub") + } + @if (_scene.Title is { } titleBottom && TitleSide(titleBottom) == BitChartPosition.Bottom) { - @RenderTitle(subBottom, "bc-subtitle") + @RenderTitle(titleBottom, "bit-cht-ttl") } - @if (_scene.Title is { Position: BitChartPosition.Bottom } titleBottom) + + @if (ShowNavigationHint) { - @RenderTitle(titleBottom, "bc-title") +
@NavigationHint
} @if (GenerateTable) @@ -192,15 +238,15 @@ @RenderDataTable() } -
@_liveMessage
+
@_liveMessage
@code { private RenderFragment RenderTitle(BitChartTitleModel title, string cls) => __builder => { var lines = title.Text.Split('\n'); -
-
+
+
@for (int i = 0; i < lines.Length; i++) { @lines[i] @@ -252,21 +298,27 @@ private RenderFragment RenderLegend(BitChartLegendModel legend) => __builder => { bool vertical = legend.Position is BitChartPosition.Left or BitChartPosition.Right; -
+
@if (!string.IsNullOrEmpty(legend.Title)) { -
@legend.Title
+
@legend.Title
} @foreach (var item in legend.Items) { -
+ @* A toggle button: the label is the accessible name and aria-pressed carries the state, + so a screen reader announces "Alpha, toggle button, pressed". *@ +
+ @item.Text + }
}; @@ -286,11 +338,12 @@ private RenderFragment RenderDataTable() => __builder => { var data = _config.Data; -
- - +
+
@ChartAriaLabel
+ @if (HasPointData) { + var budget = MaxTableRows > 0 ? MaxTableRows : int.MaxValue; @@ -299,46 +352,51 @@ { @if (ds.Points is { } pts) { - @foreach (var p in pts) + @foreach (var p in pts.Take(budget)) { - - + + } + budget -= Math.Min(budget, pts.Count); } } } else { + // Every row renders this many cells, so the header has to as well - a dataset can carry + // more values than there are category names, and a header short of them shifts the whole + // row against its labels for a screen reader. + var columns = Math.Min(TableColumnCount, TableColumnLimit); - @foreach (var label in data.Labels) + @for (int ci = 0; ci < columns; ci++) { - + } - @foreach (var ds in data.Datasets) + @foreach (var ds in MaxTableRows > 0 ? data.Datasets.Take(MaxTableRows) : data.Datasets) { @if (ds.RangeData is { } ranges) { - @foreach (var r in ranges) + @for (int ci = 0; ci < columns; ci++) { - + } } else { - @foreach (var v in ds.Data) + @for (int ci = 0; ci < columns; ci++) { - + } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor.cs index 171571a67e..4fa8941899 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor.cs @@ -1,3 +1,4 @@ +using System.Globalization; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using Microsoft.JSInterop; @@ -11,40 +12,104 @@ namespace Bit.BlazorUI; /// public partial class BitChart : ComponentBase, IAsyncDisposable { + /// Accessible label for the chart. When null a summary is generated. + [Parameter] public string? AriaLabel { get; set; } + + /// Custom CSS class applied to the root element. + [Parameter] public string? Class { get; set; } + /// Full configuration (type + data + options). Takes precedence when set. [Parameter] public BitChartConfig? Config { get; set; } - [Parameter] public BitChartType Type { get; set; } = BitChartType.Line; + /// The chart data: labels and datasets. [Parameter] public BitChartData? Data { get; set; } - [Parameter] public BitChartOptions? Options { get; set; } - /// CSS width of the chart container. - [Parameter] public string Width { get; set; } = "100%"; + /// Text direction of the chrome around the plot (title, legend, tooltip, data table). + [Parameter] public BitDir? Dir { get; set; } + + /// + /// Plays the entry and update animations even when the user has asked for reduced motion. Like every + /// other animated component in the library, the chart honors prefers-reduced-motion: reduce by + /// default and draws itself straight in its final state; this renders the library-wide bit-fam + /// opt-out class, which an ancestor can carry as well to opt a whole subtree back in. + /// + [Parameter] public bool ForceAnimation { get; set; } + + /// Render a visually-hidden data table for screen readers (default true). + [Parameter] public bool GenerateTable { get; set; } = true; + /// Optional CSS height. When null the height follows the aspect ratio. [Parameter] public string? Height { get; set; } - [Parameter] public string? Class { get; set; } - [Parameter] public string? Style { get; set; } + /// + /// Additional HTML attributes applied to the root element, following the same convention as the rest + /// of the library: assign the dictionary explicitly rather than relying on unmatched-value capture. + /// + [Parameter] public Dictionary HtmlAttributes { get; set; } = []; - /// Accessible label for the chart. When null a summary is generated. - [Parameter] public string? AriaLabel { get; set; } + /// Id of the root element. + [Parameter] public string? Id { get; set; } - /// Render a visually-hidden data table for screen readers (default true). - [Parameter] public bool GenerateTable { get; set; } = true; + /// + /// Upper bound on the columns the screen-reader table renders. A value series is one table row with + /// a cell per category, so a long series is wide rather than tall and the row cap alone would not + /// stop it; past this limit the table shows the first columns and its caption says how many were + /// left out. Ignored for point (scatter/bubble) data, whose table is three fixed columns. + /// + [Parameter] public int MaxTableColumns { get; set; } = 100; /// - /// When true (the default), entry/update animations are disabled for users who have requested - /// reduced motion (the prefers-reduced-motion: reduce media query). Set to false to always - /// animate regardless of the OS setting. + /// Upper bound on the rows the screen-reader table renders. A long series would otherwise put tens + /// of thousands of hidden nodes in the DOM for no one's benefit; past the limit the table shows the + /// first rows and its caption says how many were left out. /// - [Parameter] public bool RespectReducedMotion { get; set; } = true; + [Parameter] public int MaxTableRows { get; set; } = 500; - /// Optional custom tooltip template. When set it replaces the default tooltip body. - [Parameter] public RenderFragment? TooltipTemplate { get; set; } + /// + /// A visually hidden sentence telling a screen-reader user how to walk the data, pointed at by the + /// chart's aria-describedby alongside the data table. Without it the chart announces itself + /// as a picture and nothing says the arrow keys do anything. Set it to null or an empty string to + /// leave it out; it is only rendered when there is data to navigate. + /// + [Parameter] public string? NavigationHint { get; set; } = + "Interactive chart. Use the left and right arrow keys to move through a series, " + + "the up and down arrow keys to move between series, Home and End for the first and last value, " + + "Enter to select, and Escape to leave."; + + /// Custom content shown in place of the plot when there is nothing to draw. + [Parameter] public RenderFragment? NoDataTemplate { get; set; } + + /// Message shown in place of the plot when there is nothing to draw. + [Parameter] public string NoDataText { get; set; } = "No data to display"; /// Raised when a data element is clicked: (datasetIndex, dataIndex). [Parameter] public EventCallback<(int DatasetIndex, int DataIndex)> OnElementClick { get; set; } + /// Raised when the active (hovered or keyboard-focused) element set changes. The context + /// is null when nothing is active any more. + [Parameter] public EventCallback OnElementHover { get; set; } + + /// Raised when a legend item is clicked, before the default visibility toggle runs. + [Parameter] public EventCallback OnLegendItemClick { get; set; } + + /// Raised after zoom or pan changes the visible axis ranges. + [Parameter] public EventCallback OnZoomChange { get; set; } + + /// The chart options: scales, plugins, interaction, animation, culture and zoom. + [Parameter] public BitChartOptions? Options { get; set; } + + /// Custom CSS style applied to the root element. + [Parameter] public string? Style { get; set; } + + /// Optional custom tooltip template. When set it replaces the default tooltip body. + [Parameter] public RenderFragment? TooltipTemplate { get; set; } + + /// The chart type. Ignored when is set. + [Parameter] public BitChartType Type { get; set; } = BitChartType.Line; + + /// CSS width of the chart container. + [Parameter] public string Width { get; set; } = "100%"; + private readonly BitChartRenderState _state = new(); private BitChartConfig _config = new(); private BitChartScene _scene = new(); @@ -61,7 +126,6 @@ public partial class BitChart : ComponentBase, IAsyncDisposable private bool _suppressTransition; // Interaction state (does not trigger a scene rebuild). - private BitChartDataElement? _hovered; private readonly HashSet _active = new(); private BitChartTooltipInfo? _activeTooltip; private BitChartTooltipContext? _tooltipContext; @@ -71,6 +135,13 @@ public partial class BitChart : ComponentBase, IAsyncDisposable private int _focusIndex = -1; private string? _liveMessage; + // What the current hover/focus points at, in data coordinates rather than by element identity. + // A rebuild replaces every element object, so this is what lets an active tooltip - or the + // keyboard position - survive a re-render driven by the parent, a resize, or a zoom. + private (int Ds, int Di)? _hoverAnchor; + private bool _hoverForceIndex; + private (int Ds, int Di)? _focusKey; + // Increments to (re)play entry animations: on data change and after the first size measurement. private int _animKey; private long _lastSig = long.MinValue; @@ -81,12 +152,13 @@ public partial class BitChart : ComponentBase, IAsyncDisposable private ElementReference _plotEl; private IJSObjectReference? _zoomHandle; private DotNetObjectReference? _dotRef; - private bool _zoomRegistered; + /// What the gesture bridge is currently registered for; null until the first attempt. + private string? _zoomSignature; // Drag-zoom selection box in viewBox coordinates (x, y, w, h). private (double X, double Y, double W, double H)? _dragBox; - // Unique id for this instance's SVG defs (clip paths, gradients). + // Unique id for this instance's SVG defs (clip paths, gradients, patterns) and the a11y table. private readonly string _instanceId = "bc" + Guid.NewGuid().ToString("N")[..8]; protected override void OnParametersSet() @@ -100,14 +172,16 @@ protected override async Task OnAfterRenderAsync(bool firstRender) // A resize-triggered render suppresses geometry transitions; re-enable for later updates. if (_suppressTransition) _suppressTransition = false; - // Responsive sizing: observe the container so we can render at real device pixels. - if (_config.Options.Responsive && !_sizeRegistered) + // The pointer/keyboard bridge is attached for every chart - it is what stops the arrow keys + // scrolling the page while the chart has focus - and additionally observes the container size + // when the chart is responsive, so it can render at real device pixels. + if (!_sizeRegistered) { _sizeRegistered = true; try { _dotRef ??= DotNetObjectReference.Create(this); - _sizeHandle = await JS.BitChartObserve(_plotEl, _dotRef); + _sizeHandle = await JS.BitChartObserve(_plotEl, _dotRef, _config.Options.Responsive); } catch { @@ -116,10 +190,25 @@ protected override async Task OnAfterRenderAsync(bool firstRender) } } - if (_zoomRegistered || !_config.Options.Zoom.Enabled || _scene.IsRadialOrCircular) - return; - _zoomRegistered = true; + // The gesture bridge is keyed by what it was asked to listen for, so turning zoom off (or + // switching between panning and drag-to-zoom) at runtime tears the old listeners down instead + // of leaving the chart reacting to gestures it no longer offers. var z = _config.Options.Zoom; + bool wantZoom = z.Enabled && !_scene.IsRadialOrCircular; + bool pan = z.Pan && !z.DragZoom; + string signature = wantZoom ? $"{z.Wheel}|{pan}|{z.DragZoom}" : ""; + if (_zoomSignature == signature) return; + + if (_zoomHandle is not null) + { + try { await _zoomHandle.InvokeVoidAsync("dispose"); await _zoomHandle.DisposeAsync(); } + catch (JSDisconnectedException) { } + catch (Exception) { } + _zoomHandle = null; + } + _zoomSignature = signature; + if (!wantZoom) return; + try { _dotRef ??= DotNetObjectReference.Create(this); @@ -127,12 +216,12 @@ protected override async Task OnAfterRenderAsync(bool firstRender) // anonymous type members in release builds, which breaks System.Text.Json // serialization during the JS interop call. _zoomHandle = await JS.BitChartRegister(_plotEl, _dotRef, - new BitChartZoomPayload { Wheel = z.Wheel, Pan = z.Pan && !z.DragZoom, Drag = z.DragZoom }); + new BitChartZoomPayload { Wheel = z.Wheel, Pan = pan, Drag = z.DragZoom }); } catch { - // Interop unavailable (e.g. during prerender) - zoom stays inert. - _zoomRegistered = false; + // Interop unavailable (e.g. during prerender) - zoom stays inert until the next render. + _zoomSignature = null; } } @@ -163,11 +252,29 @@ public void OnWheelZoom(double fracX, double fracY, double deltaY) double cursor = min + t * (max - min); double nMin = cursor - (cursor - min) * factor; double nMax = cursor + (max - cursor) * factor; - if (nMax - nMin > 1e-9) _state.AxisRanges[id] = (nMin, nMax); + ApplyRange(id, nMin, nMax); } - _suppressTransition = true; - Recompute(); - StateHasChanged(); + AfterZoom(); + } + + /// + /// Invoked while two fingers pinch the chart. Unlike the wheel, which arrives in notches and steps by + /// a fixed fraction, a pinch reports how far apart the fingers have moved, so the zoom follows it + /// continuously: spreading them (a scale above 1) zooms in around the point between them. + /// + [JSInvokable] + public void OnPinchZoom(double fracX, double fracY, double scale) + { + if (!double.IsFinite(scale) || scale <= 0) return; + double factor = 1 / scale; + foreach (var id in AxesForMode()) + { + double t = AxisFraction(id, fracX, fracY); + var (min, max) = CurrentRange(id); + double cursor = min + t * (max - min); + ApplyRange(id, cursor - (cursor - min) * factor, cursor + (max - cursor) * factor); + } + AfterZoom(); } [JSInvokable] @@ -192,25 +299,44 @@ public void OnDragEnd(double x0, double y0, double x1, double y1) double lo = Math.Min(ta, tb), hi = Math.Max(ta, tb); var (min, max) = CurrentRange(id); double span = max - min; - double nMin = min + lo * span, nMax = min + hi * span; - if (nMax - nMin > 1e-9) _state.AxisRanges[id] = (nMin, nMax); + ApplyRange(id, min + lo * span, min + hi * span); } - _suppressTransition = true; - Recompute(); - StateHasChanged(); + AfterZoom(); } - /// Converts an element fraction (0..1) to a 0..1 position along an axis, via the plot area. + /// + /// How an axis is laid out. Which axis runs across the plot follows the chart's index axis, not the + /// axis' name: the value axes of a horizontal-bar chart are the horizontal ones. The fallback covers + /// a scene with no cartesian layout, where nothing will be zoomed anyway. + /// + private (bool Horizontal, bool MinAtFar) Orientation(string id) + => _scene.AxisOrientations.TryGetValue(id, out var o) ? o : (id == "x", id != "x"); + + /// + /// Converts an element fraction (0..1) to a 0..1 position along an axis, via the plot area. A + /// reversed axis runs the other way, so the fraction is flipped with it - otherwise wheel zoom and + /// pan would move away from the pointer. + /// private double AxisFraction(string id, double fracX, double fracY) { - if (_scene.PlotArea is not { } p) return id == "x" ? fracX : 1 - fracY; - if (id == "x") + var (horizontal, minAtFar) = Orientation(id); + double t; + if (_scene.PlotArea is not { } p) + { + t = horizontal ? fracX : minAtFar ? 1 - fracY : fracY; + } + else if (horizontal) { double x = fracX * _vw; - return p.Width <= 0 ? 0 : Math.Clamp((x - p.Left) / p.Width, 0, 1); + t = p.Width <= 0 ? 0 : Math.Clamp((x - p.Left) / p.Width, 0, 1); + } + else + { + double y = fracY * _vh; + double along = p.Height <= 0 ? 0 : Math.Clamp((y - p.Top) / p.Height, 0, 1); + t = minAtFar ? 1 - along : along; } - double y = fracY * _vh; - return p.Height <= 0 ? 0 : Math.Clamp(1 - (y - p.Top) / p.Height, 0, 1); + return _scene.ReversedAxes.Contains(id) ? 1 - t : t; } [JSInvokable] @@ -220,31 +346,159 @@ public void OnPan(double dx, double dy) { var (min, max) = CurrentRange(id); double span = max - min; - double delta = id == "x" ? -dx * span : dy * span; - _state.AxisRanges[id] = (min + delta, max + delta); + var (horizontal, minAtFar) = Orientation(id); + // Dragging moves the data with the pointer, so the range moves against it. + double delta = horizontal ? -dx * span : (minAtFar ? dy : -dy) * span; + if (_scene.ReversedAxes.Contains(id)) delta = -delta; + ApplyRange(id, min + delta, max + delta); } - _suppressTransition = true; - Recompute(); - StateHasChanged(); + AfterZoom(); } [JSInvokable] - public void OnResetZoom() + public void OnResetZoom() => ResetZoom(); + + /// Clears every zoom/pan override and returns the chart to the full data range. + public void ResetZoom() { + if (_state.AxisRanges.Count == 0) return; _state.AxisRanges.Clear(); + AfterZoom(); + } + + /// Zooms an axis to an explicit value range. Pass null to clear that axis's override. + public void ZoomTo(string axisId, double? min, double? max) + { + if (min is { } lo && max is { } hi && hi > lo) ApplyRange(axisId, lo, hi); + else _state.AxisRanges.Remove(axisId); + AfterZoom(); + } + + /// The visible range of an axis (its zoomed range when zoomed, else the full data range). + public (double Min, double Max)? GetAxisRange(string axisId) + => _scene.AxisRanges.TryGetValue(axisId, out var r) ? r : null; + + // ---- imperative API ---- + + /// + /// Rebuilds and redraws the chart from its current data and options. Blazor only re-renders a + /// component when a parameter it can compare changes, so mutating the object in + /// place - appending a point to a live series, editing a value - leaves the chart showing the old + /// scene until this is called. Mirrors Chart.js's chart.update(). + /// + public void Refresh() + { + Recompute(); + StateHasChanged(); + } + + /// Whether a dataset is currently drawn (neither hidden through the legend nor by + /// ). + public bool IsDatasetVisible(int datasetIndex) + { + if (datasetIndex < 0 || datasetIndex >= _config.Data.Datasets.Count) return false; + return !_config.Data.Datasets[datasetIndex].Hidden && !_state.IsDatasetHidden(datasetIndex); + } + + /// + /// Shows or hides a dataset, exactly as clicking its legend entry would. A dataset whose + /// is set stays hidden: that is the data's own answer, and + /// this only drives the chart's own visibility state. + /// + public void SetDatasetVisible(int datasetIndex, bool visible) + { + if (datasetIndex < 0 || datasetIndex >= _config.Data.Datasets.Count) return; + bool changed = visible ? _state.HiddenDatasets.Remove(datasetIndex) : _state.HiddenDatasets.Add(datasetIndex); + if (!changed) return; + Refresh(); + } + + /// Flips a dataset between shown and hidden. Mirrors Chart.js's hide/show pair. + public void ToggleDataset(int datasetIndex) => SetDatasetVisible(datasetIndex, !IsDatasetVisible(datasetIndex)); + + /// Whether a data index (a pie/doughnut/polar-area slice) is currently drawn. + public bool IsDataIndexVisible(int dataIndex) => !_state.IsIndexHidden(dataIndex); + + /// + /// Shows or hides one data index across the chart - the slice-level counterpart of + /// , used by the pie/doughnut/polar-area legend. Mirrors Chart.js's + /// toggleDataVisibility. + /// + public void SetDataIndexVisible(int dataIndex, bool visible) + { + if (dataIndex < 0) return; + bool changed = visible ? _state.HiddenIndices.Remove(dataIndex) : _state.HiddenIndices.Add(dataIndex); + if (!changed) return; + Refresh(); + } + + /// Flips one data index between shown and hidden. + public void ToggleDataIndex(int dataIndex) => SetDataIndexVisible(dataIndex, IsDataIndexVisible(dataIndex) is false); + + /// Brings back every dataset and data index hidden through the legend or the API. + public void ResetVisibility() + { + if (_state.HiddenDatasets.Count == 0 && _state.HiddenIndices.Count == 0) return; + _state.HiddenDatasets.Clear(); + _state.HiddenIndices.Clear(); + Refresh(); + } + + /// + /// Stores a new range for an axis, honoring the configured zoom limits so the chart can neither be + /// zoomed in past nor dragged outside the data. + /// + private void ApplyRange(string id, double min, double max) + { + if (double.IsNaN(min) || double.IsNaN(max) || max - min <= 1e-9) return; + var z = _config.Options.Zoom; + if (_scene.DataRanges.TryGetValue(id, out var full)) + { + double fullSpan = full.Max - full.Min; + if (fullSpan > 0) + { + double minSpan = fullSpan * Math.Clamp(z.MinRangeFraction, 0, 1); + if (minSpan > 0 && max - min < minSpan) + { + double c = (min + max) / 2; + min = c - minSpan / 2; + max = c + minSpan / 2; + } + if (z.LimitToData) + { + double span = Math.Min(max - min, fullSpan); + if (min < full.Min) { min = full.Min; max = min + span; } + if (max > full.Max) { max = full.Max; min = max - span; } + min = Math.Max(min, full.Min); + max = Math.Min(max, full.Max); + if (max - min <= 1e-9) return; + } + } + } + _state.AxisRanges[id] = (min, max); + } + + private void AfterZoom() + { _suppressTransition = true; Recompute(); StateHasChanged(); + if (OnZoomChange.HasDelegate) _ = OnZoomChange.InvokeAsync(); } + /// + /// The axes a gesture moves. The mode names a direction on screen, not an axis id: X is whatever + /// runs across the plot, which on a horizontal-bar chart is the value axis and not the one called + /// "x", and which includes a secondary x axis rather than only the primary one. + /// private IEnumerable AxesForMode() { var mode = _config.Options.Zoom.Mode; foreach (var id in _scene.ZoomableAxes) { - bool isX = id == "x"; - if (mode == BitChartZoomMode.X && !isX) continue; - if (mode == BitChartZoomMode.Y && isX) continue; + bool horizontal = Orientation(id).Horizontal; + if (mode == BitChartZoomMode.X && !horizontal) continue; + if (mode == BitChartZoomMode.Y && horizontal) continue; yield return id; } } @@ -273,9 +527,8 @@ private void Recompute() else _vh = responsive && _measuredHeight is { } mh && mh > 0 ? mh : basis / aspect; - _scene = new BitChartRenderer(_config, _state, _vw, _vh).Render(); - ClearHover(); - _focusIndex = -1; + _scene = new BitChartRenderer(_config, _state, _vw, _vh, _instanceId).Render(); + RestoreInteraction(); // Decide whether to (re)play the entry animation. We key off a signature of the data // values (not pixel positions), so data changes replay the animation while resize/zoom/pan @@ -293,6 +546,50 @@ private void Recompute() _initialized = true; } + /// + /// Re-points the hover and keyboard position at the freshly built scene. Every element object is + /// new after a render, so an active tooltip would otherwise blink out on any re-render the reader + /// did not ask for - a parent's StateHasChanged, a container resize, a zoom step. The + /// position is re-found by (dataset, index); when the data it pointed at is gone (hidden through + /// the legend, say) the interaction is simply dropped. Nothing is raised: no one interacted. + /// + private void RestoreInteraction() + { + var anchor = _hoverAnchor; + bool forceIndex = _hoverForceIndex; + var focusKey = _focusKey; + + ClearHover(); + _focusIndex = -1; + + if (focusKey is { } fk) + { + int at = _scene.Elements.FindIndex(e => e.DatasetIndex == fk.Ds && e.DataIndex == fk.Di); + if (at >= 0) + { + _focusIndex = at; + var el = _scene.Elements[at]; + BuildHover(el); + _hoverNodes.Add(FocusOutline(el)); + _liveMessage = Describe(el); + return; + } + _focusKey = null; + _liveMessage = null; + // The data being walked is gone - hidden through the legend, or removed. Anyone tracking the + // active element has to be told, or they keep showing a reading the chart no longer has. + NotifyHover(); + return; + } + + if (anchor is not { } a) return; + + if (_scene.Elements.FirstOrDefault(e => e.DatasetIndex == a.Ds && e.DataIndex == a.Di) is { } hovered) + BuildHover(hovered, forceIndex); + else + NotifyHover(); + } + /// A cheap signature of the data values driving the chart (changes when data changes). /// Animation settings are folded in so that changing duration/easing/stagger replays the entry /// animation, giving immediate visual feedback when those options are tweaked. @@ -320,35 +617,105 @@ private long ComputeSignature() private void OnEnter(BitChartDataElement e) { - _hovered = e; BuildHover(e); + NotifyHover(); + } + + /// + /// Hovering the empty part of the plot activates the whole index under the pointer, which is what + /// makes lines drawn without markers - and thin bars - reachable. + /// + private void OnEnterBand(BitChartHitBand band) + { + if (RepresentativeOf(band) is not { } rep) return; + BuildHover(rep, forceIndexGroup: true); + NotifyHover(); + } + + /// The element a band stands for: the first one at that index. + private BitChartDataElement? RepresentativeOf(BitChartHitBand band) + => _scene.Elements.FirstOrDefault(el => el.DataIndex == band.DataIndex); + + /// + /// Clicking the plate between the elements reports the index under the pointer, matching what + /// hovering there already does - with non-intersecting interaction the whole plot is the target, + /// so a click that lands beside a thin line should not be silently dropped. + /// + private async Task OnClickBand(BitChartHitBand band) + { + if (RepresentativeOf(band) is { } rep) await OnClickElement(rep); + } + + private void OnLeave() + { + ClearHover(); + NotifyHover(); + } + + /// + /// A touch screen never hovers, so a tap has to do the work mouseenter does with a mouse. + /// Only non-mouse pointers are handled: a mouse has already hovered by the time it presses, and + /// re-running the hover there would rebuild the tooltip twice for one click. + /// + private void OnPointerDownElement(PointerEventArgs args, BitChartDataElement e) + { + if (IsMouse(args)) return; + OnEnter(e); + } + + private void OnPointerDownBand(PointerEventArgs args, BitChartHitBand band) + { + if (IsMouse(args)) return; + OnEnterBand(band); } - private void OnLeave() => ClearHover(); + private static bool IsMouse(PointerEventArgs args) + => string.IsNullOrEmpty(args.PointerType) || args.PointerType == "mouse"; + + private void OnBlur() + { + if (_focusIndex < 0) return; + _focusIndex = -1; + _focusKey = null; + ClearHover(); + _liveMessage = null; + NotifyHover(); + } + + private void NotifyHover() + { + if (OnElementHover.HasDelegate) _ = OnElementHover.InvokeAsync(_tooltipContext); + } private void ClearHover() { - _hovered = null; _active.Clear(); _activeTooltip = null; _tooltipContext = null; _hoverNodes.Clear(); + _hoverAnchor = null; } - private void BuildHover(BitChartDataElement e) + private void BuildHover(BitChartDataElement e, bool forceIndexGroup = false) { _active.Clear(); _hoverNodes.Clear(); + _hoverAnchor = (e.DatasetIndex, e.DataIndex); + _hoverForceIndex = forceIndexGroup; var tip = _config.Options.Plugins.Tooltip; + var mode = tip.Mode ?? _config.Options.Interaction.Mode; - IEnumerable group = tip.Mode switch - { - BitChartInteractionMode.Index or BitChartInteractionMode.X or BitChartInteractionMode.Y when !_scene.IsRadialOrCircular - => _scene.Elements.Where(x => x.DataIndex == e.DataIndex), - BitChartInteractionMode.Dataset - => _scene.Elements.Where(x => x.DatasetIndex == e.DatasetIndex), - _ => new[] { e } - }; + IEnumerable group = + forceIndexGroup && !_scene.IsRadialOrCircular && mode != BitChartInteractionMode.Dataset + ? _scene.Elements.Where(x => x.DataIndex == e.DataIndex) + : mode switch + { + BitChartInteractionMode.Index or BitChartInteractionMode.X or BitChartInteractionMode.Y when !_scene.IsRadialOrCircular + => _scene.Elements.Where(x => x.DataIndex == e.DataIndex), + BitChartInteractionMode.Dataset + => _scene.Elements.Where(x => x.DatasetIndex == e.DatasetIndex), + _ => new[] { e } + }; foreach (var el in group) _active.Add(el); @@ -360,39 +727,67 @@ BitChartInteractionMode.Index or BitChartInteractionMode.X or BitChartInteractio AnchorY = e.Tooltip.AnchorY }; var ordered = _active.OrderBy(a => a.DatasetIndex).ToList(); - foreach (var el in ordered) - combined.Items.AddRange(el.Tooltip.Items); - // ---- Tooltip callbacks (title / body extras / footer / label color) ---- + // ---- Tooltip callbacks (title / body extras / footer / label color) + filter/sort ---- var cb = tip.Callbacks; - if (cb.Title is not null || cb.BeforeBody is not null || cb.AfterBody is not null - || cb.Footer is not null || cb.LabelColor is not null) + var items = ordered.Select(a => new BitChartTooltipItemContext { - var items = ordered.Select(a => new BitChartTooltipItemContext - { - DatasetIndex = a.DatasetIndex, - DataIndex = a.DataIndex, - DatasetLabel = a.SeriesLabel, - Label = a.Tooltip.Title, - Value = a.Value, - Color = a.Tooltip.Items.FirstOrDefault()?.Color ?? "#000", - FormattedValue = a.Tooltip.Items.FirstOrDefault()?.Text ?? "" - }).ToList(); + DatasetIndex = a.DatasetIndex, + DataIndex = a.DataIndex, + DatasetLabel = a.SeriesLabel, + Label = a.Tooltip.Title, + Value = a.Value, + Color = a.Tooltip.Items.FirstOrDefault()?.Color ?? "#000", + FormattedValue = a.Tooltip.Items.FirstOrDefault()?.Text ?? "" + }).ToList(); + + if (tip.Filter is { } filter) + { + for (int i = items.Count - 1; i >= 0; i--) + if (!filter(items[i])) { items.RemoveAt(i); ordered.RemoveAt(i); } - if (cb.Title?.Invoke(items) is { } titleText) combined.Title = titleText; - if (cb.BeforeBody?.Invoke(items) is { } bb) combined.BeforeBody.AddRange(bb.Split('\n')); - if (cb.AfterBody?.Invoke(items) is { } ab) combined.AfterBody.AddRange(ab.Split('\n')); - if (cb.Footer?.Invoke(items) is { } ft) combined.Footer.AddRange(ft.Split('\n')); - if (cb.LabelColor is not null) - for (int i = 0; i < combined.Items.Count && i < items.Count; i++) - if (cb.LabelColor(items[i]) is { } lc) combined.Items[i].Color = lc; + // A filtered-out item is not part of the hover any more: the active set is what the + // Average positioner reads and what paints the active class, so it is trimmed too. + if (ordered.Count != _active.Count) + { + _active.Clear(); + foreach (var el in ordered) _active.Add(el); + } + } + if (tip.ItemSort is { } sort) + { + var pairs = items.Zip(ordered).ToList(); + pairs.Sort((a, b) => sort(a.First, b.First)); + items = pairs.Select(p => p.First).ToList(); + ordered = pairs.Select(p => p.Second).ToList(); } - // Positioner. + foreach (var el in ordered) + combined.Items.AddRange(el.Tooltip.Items); + + if (cb.Title?.Invoke(items) is { } titleText) combined.Title = titleText; + if (cb.BeforeBody?.Invoke(items) is { } bb) combined.BeforeBody.AddRange(bb.Split('\n')); + if (cb.AfterBody?.Invoke(items) is { } ab) combined.AfterBody.AddRange(ab.Split('\n')); + if (cb.Footer?.Invoke(items) is { } ft) combined.Footer.AddRange(ft.Split('\n')); + if (cb.LabelColor is not null) + for (int i = 0; i < combined.Items.Count && i < items.Count; i++) + if (cb.LabelColor(items[i]) is { } lc) combined.Items[i].Color = lc; + + // Positioner. Averaging runs along the axis the active items share - the index axis - so on a + // horizontal-bar chart that is the vertical one, and the tooltip is put beside the group rather + // than in the middle of it. if (tip.Position == BitChartTooltipPositioner.Average && _active.Count > 0) { - combined.AnchorX = _active.Average(a => a.CenterX); - combined.AnchorY = _active.Min(a => a.Tooltip.AnchorY); + if (_config.Options.IndexAxis == BitChartIndexAxis.Y && !_scene.IsRadialOrCircular) + { + combined.AnchorX = _active.Max(a => a.Tooltip.AnchorX); + combined.AnchorY = _active.Average(a => a.CenterY); + } + else + { + combined.AnchorX = _active.Average(a => a.CenterX); + combined.AnchorY = _active.Min(a => a.Tooltip.AnchorY); + } } _activeTooltip = combined; @@ -400,7 +795,7 @@ BitChartInteractionMode.Index or BitChartInteractionMode.X or BitChartInteractio _tooltipContext = new BitChartTooltipContext { Title = combined.Title, - Points = _active.OrderBy(a => a.DatasetIndex).Select(a => new BitChartTooltipPoint + Points = ordered.Select(a => new BitChartTooltipPoint { DatasetIndex = a.DatasetIndex, DataIndex = a.DataIndex, @@ -411,24 +806,74 @@ BitChartInteractionMode.Index or BitChartInteractionMode.X or BitChartInteractio }).ToList() }; - // Highlight overlay. - bool indexMode = tip.Mode is BitChartInteractionMode.Index or BitChartInteractionMode.X && !_scene.IsRadialOrCircular; - if (indexMode && _scene.PlotArea is { } pa) - _hoverNodes.Add(new BitChartSvgLine - { - X1 = e.CenterX, Y1 = pa.Top, X2 = e.CenterX, Y2 = pa.Bottom, - Stroke = "rgba(0,0,0,0.35)", StrokeWidth = 1, Dash = "4,3" - }); - - foreach (var el in _active) + // Crosshair for index-style highlighting. + var interaction = _config.Options.Interaction; + bool indexMode = (forceIndexGroup || mode is BitChartInteractionMode.Index or BitChartInteractionMode.X) + && !_scene.IsRadialOrCircular; + if (indexMode && interaction.Crosshair && _scene.PlotArea is { } pa) { - if (el.Shape is BitChartSvgCircle c) - _hoverNodes.Add(new BitChartSvgCircle + bool horizontalIndex = _config.Options.IndexAxis == BitChartIndexAxis.Y; + _hoverNodes.Add(horizontalIndex + ? new BitChartSvgLine { - Cx = c.Cx, Cy = c.Cy, R = c.R + 4, - Fill = "none", Stroke = c.Fill, StrokeWidth = 2, Opacity = 0.6 + X1 = pa.Left, Y1 = e.CenterY, X2 = pa.Right, Y2 = e.CenterY, + Stroke = interaction.CrosshairColor, StrokeWidth = 1, Dash = "4,3" + } + : new BitChartSvgLine + { + X1 = e.CenterX, Y1 = pa.Top, X2 = e.CenterX, Y2 = pa.Bottom, + Stroke = interaction.CrosshairColor, StrokeWidth = 1, Dash = "4,3" }); + + if (interaction.CrosshairLabel && e.Tooltip.Title is { Length: > 0 } indexLabel) + AddCrosshairLabel(indexLabel, e, pa, horizontalIndex); + } + + // The renderer precomputed each element's hover appearance, so highlighting costs no re-layout. + foreach (var el in ordered) + if (el.HoverShape is { } hs) + _hoverNodes.Add(hs); + } + + private const string FocusRingColor = "var(--bit-clr-pri, #0078d4)"; + + /// + /// Draws the active index in a chip where the crosshair meets the index axis. It reuses the tooltip + /// colors so the two read as one piece of chrome, and is clamped into the plot so it cannot spill + /// out at either end. + /// + private void AddCrosshairLabel(string text, BitChartDataElement e, BitChartArea pa, bool horizontalIndex) + { + var t = _config.Options.Plugins.Tooltip; + double fontSize = t.BodyFont.Size; + double w = BitChartTextMeasure.Width(text, fontSize) + 10; + double h = fontSize + 6; + + double cx, cy; + if (horizontalIndex) + { + // A chip wider or taller than the room it is clamped into would leave Math.Clamp with a + // minimum above its maximum, so each upper bound is held at or above its lower one. + cx = Math.Clamp(pa.Left - w / 2 - 4, w / 2, Math.Max(w / 2, _vw - w / 2)); + cy = Math.Clamp(e.CenterY, pa.Top + h / 2, Math.Max(pa.Top + h / 2, pa.Bottom - h / 2)); } + else + { + cx = Math.Clamp(e.CenterX, pa.Left + w / 2, Math.Max(pa.Left + w / 2, pa.Right - w / 2)); + cy = Math.Min(pa.Bottom + h / 2 + 3, _vh - h / 2); + } + + _hoverNodes.Add(new BitChartSvgRect + { + X = cx - w / 2, Y = cy - h / 2, Width = w, Height = h, + Rx = 3, Fill = t.BackgroundColor + }); + _hoverNodes.Add(new BitChartSvgText + { + X = cx, Y = cy, Text = text, Fill = t.TitleColor, + FontFamily = t.BodyFont.Family, FontSize = fontSize, + Anchor = "middle", Baseline = "central" + }); } private async Task OnClickElement(BitChartDataElement e) @@ -445,13 +890,19 @@ private async Task OnKeyDown(KeyboardEventArgs e) if (n == 0) return; switch (e.Key) { + // Left/right walk the series the reader is on; up/down step between the series at the same + // category, which is how a multi-series chart is actually compared. case "ArrowRight": - case "ArrowDown": - Move(1); + MoveWithinSeries(1); break; case "ArrowLeft": + MoveWithinSeries(-1); + break; + case "ArrowDown": + MoveAcrossSeries(1); + break; case "ArrowUp": - Move(-1); + MoveAcrossSeries(-1); break; case "Home": SetFocus(0); @@ -465,46 +916,113 @@ private async Task OnKeyDown(KeyboardEventArgs e) break; case "Escape": _focusIndex = -1; + _focusKey = null; ClearHover(); _liveMessage = null; + NotifyHover(); break; } } - private void Move(int dir) + /// Steps to the next/previous element of the series the reader is currently on, wrapping + /// within it. With nothing focused yet it enters the chart at the appropriate end. + private void MoveWithinSeries(int dir) { int n = _scene.Elements.Count; - if (_focusIndex < 0) SetFocus(dir > 0 ? 0 : n - 1); - else SetFocus((_focusIndex + dir + n) % n); + if (_focusIndex < 0 || _focusIndex >= n) { SetFocus(dir > 0 ? 0 : n - 1); return; } + + int current = _scene.Elements[_focusIndex].DatasetIndex; + var series = new List(); + for (int i = 0; i < n; i++) + if (_scene.Elements[i].DatasetIndex == current) series.Add(i); + + int at = series.IndexOf(_focusIndex); + if (at < 0) { SetFocus((_focusIndex + dir + n) % n); return; } + SetFocus(series[(at + dir + series.Count) % series.Count]); + } + + /// + /// Steps to the neighbouring series at the same category. When that series has nothing at this + /// category - a null, or a shorter series - the nearest category it does have is taken, so the keys + /// never dead-end. A chart of one series has nothing to step between, so the vertical keys keep + /// walking the data instead of doing nothing. + /// + private void MoveAcrossSeries(int dir) + { + int n = _scene.Elements.Count; + if (_focusIndex < 0 || _focusIndex >= n) { SetFocus(dir > 0 ? 0 : n - 1); return; } + + var current = _scene.Elements[_focusIndex]; + var datasets = _scene.Elements.Select(x => x.DatasetIndex).Distinct().OrderBy(i => i).ToList(); + if (datasets.Count < 2) { MoveWithinSeries(dir); return; } + + int at = datasets.IndexOf(current.DatasetIndex); + int target = datasets[(at + dir + datasets.Count) % datasets.Count]; + + int best = -1, bestDistance = int.MaxValue; + for (int i = 0; i < n; i++) + { + var el = _scene.Elements[i]; + if (el.DatasetIndex != target) continue; + int distance = Math.Abs(el.DataIndex - current.DataIndex); + if (distance >= bestDistance) continue; + bestDistance = distance; + best = i; + } + if (best >= 0) SetFocus(best); } private void SetFocus(int i) { _focusIndex = i; var el = _scene.Elements[i]; - _hovered = el; + _focusKey = (el.DatasetIndex, el.DataIndex); BuildHover(el); _hoverNodes.Add(FocusOutline(el)); _liveMessage = Describe(el); + NotifyHover(); } + /// + /// The ring drawn around the keyboard position. It traces the element's own outline rather than a + /// stand-in shape: a rounded bar and an arc are both paths, and a circle around an arc's centroid + /// would sit inside the ring it is supposed to be marking. + /// private static BitChartSvgNode FocusOutline(BitChartDataElement el) => el.Shape switch { - BitChartSvgRect r => new BitChartSvgRect { X = r.X - 2, Y = r.Y - 2, Width = r.Width + 4, Height = r.Height + 4, Fill = "none", Stroke = "#1a1a1a", StrokeWidth = 2, CssClass = "bc-focus-ring" }, - BitChartSvgCircle c => new BitChartSvgCircle { Cx = c.Cx, Cy = c.Cy, R = c.R + 5, Fill = "none", Stroke = "#1a1a1a", StrokeWidth = 2, CssClass = "bc-focus-ring" }, - _ => new BitChartSvgCircle { Cx = el.CenterX, Cy = el.CenterY, R = 8, Fill = "none", Stroke = "#1a1a1a", StrokeWidth = 2, CssClass = "bc-focus-ring" } + BitChartSvgRect r => new BitChartSvgRect { X = r.X - 2, Y = r.Y - 2, Width = r.Width + 4, Height = r.Height + 4, Fill = "none", Stroke = FocusRingColor, StrokeWidth = 2, CssClass = "bit-cht-focus-ring" }, + BitChartSvgCircle c => new BitChartSvgCircle { Cx = c.Cx, Cy = c.Cy, R = c.R + 5, Fill = "none", Stroke = FocusRingColor, StrokeWidth = 2, CssClass = "bit-cht-focus-ring" }, + BitChartSvgPath p => new BitChartSvgPath { D = p.D, Fill = "none", Stroke = FocusRingColor, StrokeWidth = 2, CssClass = "bit-cht-focus-ring" }, + BitChartSvgPolygon poly => new BitChartSvgPolygon { Points = [.. poly.Points], Closed = poly.Closed, Fill = "none", Stroke = FocusRingColor, StrokeWidth = 2, CssClass = "bit-cht-focus-ring" }, + _ => new BitChartSvgCircle { Cx = el.CenterX, Cy = el.CenterY, R = 8, Fill = "none", Stroke = FocusRingColor, StrokeWidth = 2, CssClass = "bit-cht-focus-ring" } }; + /// + /// What the live region says about the focused element. The position is included because a reader + /// stepping through the data has no other way to tell how far along they are, and it is counted + /// within the series - the run the left/right keys actually walk. Which series they are on is + /// announced only when there is more than one to be on. + /// private string Describe(BitChartDataElement el) { var parts = new List(); if (!string.IsNullOrEmpty(el.Tooltip.Title)) parts.Add(el.Tooltip.Title!); foreach (var item in el.Tooltip.Items) parts.Add(item.Text); + + var series = _scene.Elements.Where(x => x.DatasetIndex == el.DatasetIndex).ToList(); + int at = series.IndexOf(el); + parts.Add($"{(at < 0 ? 1 : at + 1)} of {series.Count}"); + + var datasets = _scene.Elements.Select(x => x.DatasetIndex).Distinct().OrderBy(i => i).ToList(); + if (datasets.Count > 1) + parts.Add($"series {datasets.IndexOf(el.DatasetIndex) + 1} of {datasets.Count}"); + return string.Join(", ", parts); } - private void ToggleLegend(BitChartLegendItemModel item) + private async Task ToggleLegend(BitChartLegendItemModel item) { + if (OnLegendItemClick.HasDelegate) await OnLegendItemClick.InvokeAsync(item); if (_scene.Legend is null || !_scene.Legend.OnClickToggle) return; if (item.IsDataIndex) { @@ -522,9 +1040,49 @@ private void ToggleLegend(BitChartLegendItemModel item) private string ViewBox => $"0 0 {BitChartSvg.N(_vw)} {BitChartSvg.N(_vh)}"; + private string TableId => $"{_instanceId}-table"; + + private string HintId => $"{_instanceId}-hint"; + + /// True when the keyboard hint is worth rendering: there is data to walk and text to say it with. + private bool ShowNavigationHint => !string.IsNullOrWhiteSpace(NavigationHint) && _scene.Elements.Count > 0; + + /// + /// What the chart points its aria-describedby at: the how-to-navigate sentence and the data + /// table, in that order, and null when it has neither. + /// + private string? DescribedBy + { + get + { + if (ShowNavigationHint && GenerateTable) return $"{HintId} {TableId}"; + if (ShowNavigationHint) return HintId; + return GenerateTable ? TableId : null; + } + } + private string? ClipId => _scene.PlotArea is null ? null : $"{_instanceId}-clip"; private string? ClipRef => ClipId is null ? null : $"url(#{ClipId})"; + private CultureInfo Culture => _config.Options.Culture ?? CultureInfo.InvariantCulture; + + private string Fmt(double v) => v.ToString(Culture); + + /// + /// One cell of the screen-reader table. The tooltip names an error interval beside the value, so the + /// table - which is what a reader has instead of the tooltip - has to name it too. + /// + private string CellText(BitChartDataset ds, int dataIndex) + { + if (dataIndex >= ds.Data.Count || ds.Data[dataIndex] is not { } value) return ""; + string text = Fmt(value); + if (ds.ErrorData is not { } errors || dataIndex >= errors.Count || errors[dataIndex] is not { } e) return text; + + double minus = Math.Abs(e.Minus), plus = Math.Abs(e.Plus); + if (minus <= 0 && plus <= 0) return text; + return e.IsSymmetric ? $"{text} ±{Fmt(plus)}" : $"{text} +{Fmt(plus)}/-{Fmt(minus)}"; + } + private bool AnimationEnabled => _config.Options.Animation.Animate; /// @@ -545,96 +1103,37 @@ private void ToggleLegend(BitChartLegendItemModel item) /// private bool ProgressiveDraw => CanAnimate && _scene.ProgressiveDraw; - /// - /// Global (unscoped) animation rules emitted once per chart. Kept out of the component's - /// isolated stylesheet so the rules reliably match the SVG shapes rendered by the child - /// SvgPrimitive component (which carries a different CSS-isolation scope). - /// - private const string AnimationStyles = """ - - """; - - /// - /// Opt-in reduced-motion overrides. Injected only when is true, - /// so animations/transitions are disabled for users who requested reduced motion. - /// - private const string ReducedMotionStyles = """ - - """; + private string RootClass + { + get + { + string c = "bit-cht"; + // bit-fam is the library-wide reduced-motion opt-out: without it (here or on an ancestor) + // the chart's keyframes are taken out under prefers-reduced-motion. + if (ForceAnimation) c += " bit-fam"; + if (!string.IsNullOrEmpty(Class)) c += " " + Class; + return c; + } + } private string DataGroupClass { get { - if (!CanAnimate) return "bc-data"; + if (!CanAnimate) return "bit-cht-data"; // Progressive draw: points reveal individually (per-element delay tied to x position), // so the group itself carries no animation. - if (ProgressiveDraw) return "bc-data"; + if (ProgressiveDraw) return "bit-cht-data"; // When staggering, the individual elements animate (with per-element delays) instead of // the whole group, so the group itself carries no animation. - if (Staggered) return "bc-data"; + if (Staggered) return "bit-cht-data"; if (_scene.IsRadialOrCircular) - return "bc-data bc-animate bc-anim-grow"; + return "bit-cht-data bit-cht-anim bit-cht-anim-grow"; // Bars grow from the baseline as a size change, in the correct direction for the orientation. if (_scene.HasBars) - return _scene.HorizontalBars ? "bc-data bc-animate bc-anim-bars-h" : "bc-data bc-animate bc-anim-bars-v"; + return _scene.HorizontalBars ? "bit-cht-data bit-cht-anim bit-cht-anim-bars-h" : "bit-cht-data bit-cht-anim bit-cht-anim-bars-v"; // Line/scatter points rise in. - return "bc-data bc-animate bc-anim-rise"; + return "bit-cht-data bit-cht-anim bit-cht-anim-rise"; } } @@ -661,36 +1160,39 @@ private string? DataGroupStyle private string SeriesGroupClass => CanAnimate ? ProgressiveDraw - // The stroke draws itself on (bc-draw) and fills fade in, both at the path level, + // The stroke draws itself on (bit-cht-draw) and fills fade in, both at the path level, // so the group must not also rise. - ? "bc-series" + ? "bit-cht-series" : _scene.IsRadialOrCircular - ? "bc-series bc-animate bc-anim-grow" - : "bc-series bc-animate bc-anim-rise" - : "bc-series"; + ? "bit-cht-series bit-cht-anim bit-cht-anim-grow" + : "bit-cht-series bit-cht-anim bit-cht-anim-rise" + : "bit-cht-series"; private string ElementClass(BitChartDataElement el) { - string c = "bc-el"; - if (IsActive(el)) c += " bc-active"; + string c = "bit-cht-el"; + // A state hook only: the active look itself is the precomputed hover shape drawn over the + // element, so the class carries no rule of its own and is there for consumers to style. + if (IsActive(el)) c += " bit-cht-active"; if (ProgressiveDraw) { // Each point pops in as the drawing stroke reaches it (delay set in ElementStyle). - c += " bc-el-anim bc-el-rise"; + c += " bit-cht-el-anim bit-cht-el-rise"; } else if (Staggered) { // Bars reuse the proven view-box scaling classes (with an explicit per-element pixel // transform-origin set in ElementStyle); points/markers rise in via the fill-box class. c += _scene.HasBars - ? _scene.HorizontalBars ? " bc-animate bc-anim-bars-h" : " bc-animate bc-anim-bars-v" - : " bc-el-anim bc-el-rise"; + ? _scene.HorizontalBars ? " bit-cht-anim bit-cht-anim-bars-h" : " bit-cht-anim bit-cht-anim-bars-v" + : " bit-cht-el-anim bit-cht-el-rise"; } return c; } private string ElementStyle(int index) { + string cursor = OnElementClick.HasDelegate ? "cursor:pointer" : "cursor:default"; if (ProgressiveDraw) { // Reveal each point in time with the stroke as it sweeps left to right. The delay is tied @@ -701,14 +1203,14 @@ private string ElementStyle(int index) if (_scene.PlotArea is { Width: > 0 } pa) frac = Math.Clamp((_scene.Elements[index].CenterX - pa.Left) / pa.Width, 0, 1); double pDelay = frac * Math.Max(0, dur - elDur); - return $"cursor:pointer;animation-delay:{BitChartSvg.N(pDelay)}ms;animation-duration:{BitChartSvg.N(elDur)}ms"; + return $"{cursor};animation-delay:{BitChartSvg.N(pDelay)}ms;animation-duration:{BitChartSvg.N(elDur)}ms"; } - if (!Staggered) return "cursor:pointer"; + if (!Staggered) return cursor; double delay = index * _config.Options.Animation.DelayBetween; - string s = $"cursor:pointer;animation-delay:{BitChartSvg.N(delay)}ms"; + string s = $"{cursor};animation-delay:{BitChartSvg.N(delay)}ms"; if (_scene.HasBars) { - // bc-anim-bars-* use transform-box: view-box, so the origin must be given in view-box + // bit-cht-anim-bars-* use transform-box: view-box, so the origin must be given in view-box // pixels pinned to the value-axis baseline (matching the non-staggered group behaviour). var el = _scene.Elements[index]; s += _scene.HorizontalBars @@ -719,10 +1221,64 @@ private string ElementStyle(int index) } private string AnimStyle => - $"--bc-dur:{_config.Options.Animation.Duration}ms;--bc-ease:{_config.Options.Animation.Easing}"; + $"--bit-cht-dur:{_config.Options.Animation.Duration}ms;--bit-cht-ease:{_config.Options.Animation.Easing}"; private bool IsActive(BitChartDataElement e) => _active.Count > 0 && _active.Contains(e); + /// + /// Places the tooltip above its anchor and keeps the whole box inside the plot: it flips below when + /// there is no room above, and slides horizontally so it never spills out of (and gets clipped by) + /// the chart container. The caret follows the anchor so it keeps pointing at the data. + /// + private (string Style, string CaretStyle) TooltipPlacement(BitChartTooltipInfo tt) + { + var t = _config.Options.Plugins.Tooltip; + double caret = t.Caret ? t.CaretSize : 0; + double gap = caret + 4; + + // Estimated box size: the tooltip is measured from its own text because the browser layout is + // not available on the server, and this only needs to be good enough to pick a side. + double fontW = t.BodyFont.Size; + double width = 0; + if (!string.IsNullOrEmpty(tt.Title)) + width = BitChartTextMeasure.Width(tt.Title, t.TitleFont.Size, t.TitleFont.Weight); + foreach (var item in tt.Items) + width = Math.Max(width, BitChartTextMeasure.Width(item.Text, fontW) + (t.DisplayColors ? 16 : 0)); + foreach (var line in tt.BeforeBody.Concat(tt.AfterBody).Concat(tt.Footer)) + width = Math.Max(width, BitChartTextMeasure.Width(line, fontW)); + width += t.Padding * 3; + + int lines = (string.IsNullOrEmpty(tt.Title) ? 0 : 1) + tt.Items.Count + + tt.BeforeBody.Count + tt.AfterBody.Count + tt.Footer.Count; + double height = Math.Max(1, lines) * (fontW * 1.5) + t.Padding * 2 + (tt.Footer.Count > 0 ? 8 : 0); + + // Anchor in view-box units, then clamp the box into the plot box. + double ax = tt.AnchorX, ay = tt.AnchorY; + bool below = ay - height - gap < 0; + double top = below ? ay + gap : ay - height - gap; + double left = ax - width / 2; + left = Math.Clamp(left, 2, Math.Max(2, _vw - width - 2)); + top = Math.Clamp(top, 2, Math.Max(2, _vh - height - 2)); + + // Percentages keep the tooltip aligned with the SVG, which scales with the container. An + // explicit MaxWidth also lets the text wrap, which is what makes a prose tooltip readable. + double maxWidth = t.MaxWidth ?? Math.Max(80, _vw - 8); + string style = + $"left:{BitChartSvg.N(Pct(left, _vw))}%;top:{BitChartSvg.N(Pct(top, _vh))}%;" + + $"transform:translateZ(0);max-width:{BitChartSvg.N(maxWidth)}px" + + (t.MaxWidth is null ? "" : ";white-space:normal"); + + // The caret sits on the edge facing the anchor, at the anchor's horizontal position. + double caretLeft = Math.Clamp(ax - left, caret + 2, Math.Max(caret + 2, width - caret - 2)); + string caretStyle = caret <= 0 + ? "display:none" + : below + ? $"left:{BitChartSvg.N(caretLeft - caret)}px;top:{BitChartSvg.N(-caret * 2)}px;border-width:{BitChartSvg.N(caret)}px;border-bottom-color:{t.BackgroundColor}" + : $"left:{BitChartSvg.N(caretLeft - caret)}px;bottom:{BitChartSvg.N(-caret * 2)}px;border-width:{BitChartSvg.N(caret)}px;border-top-color:{t.BackgroundColor}"; + + return (style, caretStyle); + } + private string RootStyle { get @@ -734,7 +1290,7 @@ private string RootStyle } } - private double Pct(double v, double total) => total <= 0 ? 0 : v / total * 100; + private static double Pct(double v, double total) => total <= 0 ? 0 : v / total * 100; private string ChartAriaLabel { @@ -749,6 +1305,51 @@ private string ChartAriaLabel private bool HasPointData => _config.Data.Datasets.Any(d => d.Points is { Count: > 0 }); + /// Total rows the data table would render without a cap. + private int TableRowCount => HasPointData + ? _config.Data.Datasets.Sum(d => d.Points?.Count ?? 0) + : _config.Data.Datasets.Count; + + private bool TableTruncated => MaxTableRows > 0 && TableRowCount > MaxTableRows; + + /// Total columns the value table would render without a cap (one per category). + private int TableColumnCount => HasPointData + ? 3 + : Math.Max(_config.Data.Labels.Count, _config.Data.Datasets.Count == 0 ? 0 : _config.Data.Datasets.Max(d => d.Count)); + + /// The number of category columns actually rendered. + private int TableColumnLimit => HasPointData || MaxTableColumns <= 0 + ? int.MaxValue + : MaxTableColumns; + + private bool TableColumnsTruncated => !HasPointData && MaxTableColumns > 0 && TableColumnCount > MaxTableColumns; + + /// Caption of the screen-reader table, which also carries the truncation notice. + private string TableCaption + { + get + { + var caption = ChartAriaLabel; + if (TableTruncated) + caption += $" Showing the first {MaxTableRows.ToString("N0", Culture)} of {TableRowCount.ToString("N0", Culture)} rows."; + if (TableColumnsTruncated) + caption += $" Showing the first {MaxTableColumns.ToString("N0", Culture)} of {TableColumnCount.ToString("N0", Culture)} columns."; + return caption; + } + } + + /// + /// The side a title actually renders on. Left and right titles run down the side of the plot + /// (rotated); anything that is not one of the four sides falls back to the top. + /// + private static BitChartPosition TitleSide(BitChartTitleModel title) => title.Position switch + { + BitChartPosition.Bottom => BitChartPosition.Bottom, + BitChartPosition.Left => BitChartPosition.Left, + BitChartPosition.Right => BitChartPosition.Right, + _ => BitChartPosition.Top + }; + private static string AlignToFlex(BitChartAlign a) => a switch { BitChartAlign.Start => "flex-start", @@ -773,5 +1374,6 @@ public async ValueTask DisposeAsync() catch (JSDisconnectedException) { } catch (Exception) { } _dotRef?.Dispose(); + GC.SuppressFinalize(this); } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.scss new file mode 100644 index 0000000000..c2545f52f4 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.scss @@ -0,0 +1,357 @@ +@import '../../../Bit.BlazorUI/Styles/functions.scss'; + +.bit-cht { + --bit-cht-dur: 600ms; + --bit-cht-ease: ease-out; + --bit-cht-focus: #{$clr-pri}; + + display: flex; + box-sizing: border-box; + flex-direction: column; + font-family: #{$tg-font-family}; +} + +.bit-cht-ttl, +.bit-cht-sub { + width: 100%; + display: flex; + text-align: center; +} + +// A title on the left or right runs down the side of the plot instead of across the top. +.bit-cht-ttl-v { + width: auto; + align-items: center; + writing-mode: vertical-rl; + + &:first-child { + rotate: 180deg; + } +} + +.bit-cht-mid { + flex: 1 1 auto; + display: flex; + min-height: 0; + flex-direction: row; + align-items: stretch; +} + +.bit-cht-plot { + flex: 1 1 auto; + min-width: 0; + position: relative; +} + +.bit-cht-svg { + width: 100%; + height: 100%; + display: block; + overflow: visible; + + &:focus { + outline: none; + } + + &:focus-visible { + border-radius: 4px; + outline-offset: 2px; + outline: 2px solid var(--bit-cht-focus); + } +} + +// Only the data elements and the hit bands are interactive. Without this, the line drawn over a +// band would take the pointer, and the tooltip would blink out exactly where the data is. +.bit-cht-hover, +.bit-cht-fg, +.bit-cht-bg, +.bit-cht-series { + pointer-events: none; +} + +// The cursor is set inline, from whether the chart has a click handler at all. +.bit-cht-band { + outline: none; +} + +// ---- legend ---- + +.bit-cht-lgd { + display: flex; + padding: 6px 8px; + flex-wrap: wrap; + gap: 4px 14px; +} + +.bit-cht-lgd-h { + flex-direction: row; +} + +.bit-cht-lgd-v { + flex-direction: column; + align-content: center; + justify-content: center; +} + +.bit-cht-lgd-itm { + gap: 6px; + border: none; + padding: 2px 4px; + margin: 0; + color: inherit; + font: inherit; + display: inline-flex; + background: none; + line-height: 1.4; + user-select: none; + align-items: center; + border-radius: #{$shp-radius-sm}; + + &:focus-visible { + outline-offset: 1px; + outline: 2px solid var(--bit-cht-focus); + } + + &.bit-cht-hdn { + opacity: 0.45; + text-decoration: line-through; + } +} + +.bit-cht-lgd-box { + flex: 0 0 auto; + display: inline-block; + border: 2px solid; + border-radius: 2px; +} + +.bit-cht-lgd-mrk { + flex: 0 0 auto; + overflow: visible; +} + +.bit-cht-lgd-ttl { + width: 100%; + text-align: center; + font-weight: #{$tg-fw-bold}; +} + +// ---- tooltip ---- + +.bit-cht-tt { + top: 0; + left: 0; + z-index: 10; + position: absolute; + white-space: nowrap; + pointer-events: none; + box-shadow: #{$box-shadow-popup}; + transition: left #{$mot-duration-short} linear, top #{$mot-duration-short} linear; +} + +.bit-cht-tt-ttl { + margin-bottom: 3px; +} + +.bit-cht-tt-ftr { + margin-top: 4px; + padding-top: 4px; + border-top: 1px solid rgba(255, 255, 255, 0.25); +} + +.bit-cht-tt-custom { + padding: 8px 10px; + color: #{$clr-fg-pri}; + background: #{$clr-bg-pri}; + border: 1px solid #{$clr-brd-sec}; + border-radius: #{$shp-radius-popup}; + font-size: #{$tg-fs-xs}; +} + +.bit-cht-tt-itm { + gap: 6px; + display: flex; + line-height: 1.5; + align-items: center; +} + +.bit-cht-tt-swt { + width: 10px; + height: 10px; + flex: 0 0 auto; + display: inline-block; + border-radius: 2px; +} + +.bit-cht-tt-swt-svg { + flex: 0 0 auto; + overflow: visible; +} + +// The caret is a rotated square peeking out of the tooltip box. +.bit-cht-tt-caret { + width: 0; + height: 0; + position: absolute; + border: 6px solid transparent; +} + +// ---- no data / overlay ---- + +.bit-cht-nodata { + inset: 0; + display: flex; + position: absolute; + align-items: center; + justify-content: center; + color: #{$clr-fg-sec}; + font-size: #{$tg-fs-sm}; +} + +.bit-cht-sr { + top: auto; + left: auto; + width: 1px; + border: 0; + height: 1px; + margin: -1px; + padding: 0; + position: absolute; + overflow: hidden; + white-space: nowrap; + clip: rect(0, 0, 0, 0); +} + +// ---- animations ---- + +@keyframes bit-cht-rise { + from { + opacity: 0; + transform: translateY(12px) scaleY(0.9); + } + + to { + opacity: 1; + transform: none; + } +} + +@keyframes bit-cht-grow { + from { + opacity: 0; + transform: scale(0.82); + } + + to { + opacity: 1; + transform: none; + } +} + +@keyframes bit-cht-draw { + from { + stroke-dashoffset: 1; + } + + to { + stroke-dashoffset: 0; + } +} + +@keyframes bit-cht-fade { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes bit-cht-scale-y { + from { + transform: scaleY(0); + } + + to { + transform: scaleY(1); + } +} + +@keyframes bit-cht-scale-x { + from { + transform: scaleX(0); + } + + to { + transform: scaleX(1); + } +} + +.bit-cht-anim { + animation-fill-mode: both; + animation-duration: var(--bit-cht-dur, 600ms); + animation-timing-function: var(--bit-cht-ease, ease-out); +} + +.bit-cht-anim-rise { + transform-box: view-box; + transform-origin: center bottom; + animation-name: bit-cht-rise; +} + +.bit-cht-anim-grow { + transform-box: view-box; + transform-origin: center; + animation-name: bit-cht-grow; +} + +.bit-cht-anim-bars-v { + transform-box: view-box; + transform-origin: center bottom; + animation-name: bit-cht-scale-y; +} + +.bit-cht-anim-bars-h { + transform-box: view-box; + transform-origin: left center; + animation-name: bit-cht-scale-x; +} + +.bit-cht-el-anim { + transform-box: fill-box; + animation-fill-mode: both; + animation-duration: var(--bit-cht-dur, 600ms); + animation-timing-function: var(--bit-cht-ease, ease-out); +} + +.bit-cht-el-rise { + transform-origin: center bottom; + animation-name: bit-cht-rise; +} + +.bit-cht-draw { + stroke-dasharray: 1; + animation: bit-cht-draw var(--bit-cht-dur, 600ms) var(--bit-cht-ease, ease-out) both; +} + +.bit-cht-fade { + animation: bit-cht-fade var(--bit-cht-dur, 600ms) var(--bit-cht-ease, ease-out) both; +} + +.bit-cht-focus-ring { + stroke-dasharray: 3 2; +} + +// The entry animations take their duration from the chart's own options rather than from the +// --bit-mot-duration* tokens, so they opt out of reduced motion here instead: the keyframes are taken +// out and every element is left drawn in its final state. .bit-fam is the shared opt-out class +// rendered by ForceAnimation, honored on an ancestor as well as on the chart itself, so opting a whole +// subtree back in behaves the same here as it does for the token-driven animations. +@media (prefers-reduced-motion: reduce) { + .bit-cht:not(.bit-fam):not(.bit-fam *) { + :is(.bit-cht-anim, .bit-cht-el-anim, .bit-cht-draw, .bit-cht-fade) { + animation: none; + } + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.ts b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.ts index c59eda4d39..c0c8725acf 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.ts +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.ts @@ -11,7 +11,7 @@ namespace BitBlazorUI { export class BitChart { // Observe an element's pixel size and report changes to .NET so the chart can render at real // device pixels (keeping font sizes constant, like Chart.js) instead of scaling a fixed viewBox. - public static observe(element: HTMLElement, dotnet: DotNetObject) { + public static observe(element: HTMLElement, dotnet: DotNetObject, responsive: boolean) { let lastW = 0, lastH = 0; function report() { @@ -23,19 +23,35 @@ namespace BitBlazorUI { } } + // Arrow/Home/End/Space navigate the focused chart. Blazor evaluates @onkeydown:preventDefault + // at render time, so it cannot decide per key - and cancelling every keydown would break Tab. + // A capture listener decides per key, and only while the SVG itself has focus. + const NAV_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End', ' ', 'Spacebar']; + function onKeyDown(e: KeyboardEvent) { + const target = e.target as Element | null; + if (!target || target.tagName.toLowerCase() !== 'svg') return; + if (NAV_KEYS.indexOf(e.key) >= 0) e.preventDefault(); + } + element.addEventListener('keydown', onKeyDown, true); + let ro: ResizeObserver | null = null; - if (typeof ResizeObserver !== 'undefined') { - ro = new ResizeObserver(report); - ro.observe(element); - } else { - window.addEventListener('resize', report); + let listening = false; + if (responsive) { + if (typeof ResizeObserver !== 'undefined') { + ro = new ResizeObserver(report); + ro.observe(element); + } else { + window.addEventListener('resize', report); + listening = true; + } + report(); } - report(); return { dispose() { + element.removeEventListener('keydown', onKeyDown, true); if (ro) ro.disconnect(); - else window.removeEventListener('resize', report); + if (listening) window.removeEventListener('resize', report); } }; } @@ -43,6 +59,15 @@ namespace BitBlazorUI { public static register(element: HTMLElement, dotnet: DotNetObject, opts: BitChartZoomOptions) { const state = { panning: false, lastX: 0, lastY: 0, startX: 0, startY: 0 }; + // Live touch/pen contacts, so a second finger can be recognised as a pinch. + const contacts = new Map(); + let pinchDistance = 0; + + // The browser's own pan/zoom would otherwise consume the gesture before it reaches us, + // which is why a touch drag does nothing on a chart that has not opted out of it. + const previousTouchAction = element.style.touchAction; + if (opts.pan || opts.drag || opts.wheel) element.style.touchAction = 'none'; + function frac(e: { clientX: number, clientY: number }) { const r = element.getBoundingClientRect(); return { @@ -58,8 +83,26 @@ namespace BitBlazorUI { dotnet.invokeMethodAsync('OnWheelZoom', f.x, f.y, e.deltaY); } + function distance() { + const points = Array.from(contacts.values()); + const dx = points[0].x - points[1].x; + const dy = points[0].y - points[1].y; + return Math.sqrt(dx * dx + dy * dy); + } + function onDown(e: PointerEvent) { if (e.button !== 0) return; + // Contacts are tracked whatever the pan settings are: pinching is the touch equivalent + // of the wheel, so it belongs to zoom rather than to panning. + if (e.pointerType !== 'mouse' && (opts.wheel || opts.pan || opts.drag)) { + contacts.set(e.pointerId, { x: e.clientX, y: e.clientY }); + if (contacts.size === 2) { + // A second finger turns the gesture into a pinch, so the pan stops here. + state.panning = false; + pinchDistance = distance(); + return; + } + } if (!opts.pan && !opts.drag) return; state.panning = true; state.lastX = e.clientX; @@ -71,6 +114,24 @@ namespace BitBlazorUI { } function onMove(e: PointerEvent) { + if (contacts.has(e.pointerId)) contacts.set(e.pointerId, { x: e.clientX, y: e.clientY }); + + if (contacts.size === 2 && opts.wheel) { + const next = distance(); + if (pinchDistance > 0 && next > 0) { + const points = Array.from(contacts.values()); + const r = element.getBoundingClientRect(); + const midX = (points[0].x + points[1].x) / 2; + const midY = (points[0].y + points[1].y) / 2; + dotnet.invokeMethodAsync('OnPinchZoom', + r.width ? (midX - r.left) / r.width : 0.5, + r.height ? (midY - r.top) / r.height : 0.5, + next / pinchDistance); + } + pinchDistance = next; + return; + } + if (!state.panning) return; const r = element.getBoundingClientRect(); if (opts.drag) { @@ -89,6 +150,8 @@ namespace BitBlazorUI { } function onUp(e: PointerEvent) { + contacts.delete(e.pointerId); + if (contacts.size < 2) pinchDistance = 0; if (!state.panning) return; state.panning = false; element.style.cursor = ''; @@ -110,6 +173,7 @@ namespace BitBlazorUI { element.addEventListener('pointerdown', onDown); element.addEventListener('pointermove', onMove); window.addEventListener('pointerup', onUp); + window.addEventListener('pointercancel', onUp); element.addEventListener('dblclick', onDouble); return { @@ -118,9 +182,135 @@ namespace BitBlazorUI { element.removeEventListener('pointerdown', onDown); element.removeEventListener('pointermove', onMove); window.removeEventListener('pointerup', onUp); + window.removeEventListener('pointercancel', onUp); element.removeEventListener('dblclick', onDouble); + element.style.touchAction = previousTouchAction; } }; } + + // ---- export ---- + + // Theme tokens the chart references from SVG attributes as var(--bit-...). They resolve against + // the document, so an exported (standalone) SVG has to carry their computed values with it. + private static readonly THEME_VARS = [ + '--bit-clr-fg-pri', '--bit-clr-fg-sec', '--bit-clr-brd-pri', '--bit-clr-brd-sec', + '--bit-clr-bg-pri', '--bit-clr-pri', '--bit-tpg-font-family' + ]; + + private static serialize(element: HTMLElement, background: string | null): string | null { + const svg = element.querySelector('svg') as SVGSVGElement | null; + if (!svg) return null; + + const clone = svg.cloneNode(true) as SVGSVGElement; + const box = svg.getBoundingClientRect(); + const width = Math.max(1, Math.round(box.width)); + const height = Math.max(1, Math.round(box.height)); + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + clone.setAttribute('width', String(width)); + clone.setAttribute('height', String(height)); + clone.style.overflow = 'visible'; + + // Interaction-only layers are not part of the picture. + clone.querySelectorAll('.bit-cht-hover, .bit-cht-bands').forEach(n => n.remove()); + + const computed = getComputedStyle(svg); + for (const name of BitChart.THEME_VARS) { + const value = computed.getPropertyValue(name); + if (value) clone.style.setProperty(name, value.trim()); + } + if (background) { + const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + rect.setAttribute('width', '100%'); + rect.setAttribute('height', '100%'); + rect.setAttribute('fill', background); + clone.insertBefore(rect, clone.firstChild); + } + return new XMLSerializer().serializeToString(clone); + } + + public static exportSvg(element: HTMLElement, fileName: string, background: string | null) { + const markup = BitChart.serialize(element, background); + if (!markup) return false; + BitChart.downloadBlob(fileName || 'chart.svg', new Blob([markup], { type: 'image/svg+xml;charset=utf-8' })); + return true; + } + + // Rasterizes the serialized SVG onto a canvas the caller can then read as a blob or a data URL. + private static async rasterize(element: HTMLElement, scale: number, background: string | null) { + const markup = BitChart.serialize(element, background); + if (!markup) return null; + const svg = element.querySelector('svg') as SVGSVGElement; + const box = svg.getBoundingClientRect(); + const ratio = Math.max(1, scale || 1); + const width = Math.max(1, Math.round(box.width * ratio)); + const height = Math.max(1, Math.round(box.height * ratio)); + + const url = URL.createObjectURL(new Blob([markup], { type: 'image/svg+xml;charset=utf-8' })); + try { + const image = new Image(); + image.width = width; + image.height = height; + await new Promise((resolve, reject) => { + image.onload = () => resolve(); + image.onerror = () => reject(new Error('svg load failed')); + image.src = url; + }); + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext('2d'); + if (!ctx) return null; + if (background) { + ctx.fillStyle = background; + ctx.fillRect(0, 0, width, height); + } + ctx.drawImage(image, 0, 0, width, height); + return canvas; + } finally { + URL.revokeObjectURL(url); + } + } + + public static async exportPng(element: HTMLElement, fileName: string, scale: number, background: string | null) { + const canvas = await BitChart.rasterize(element, scale, background); + if (!canvas) return false; + const blob: Blob | null = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); + if (!blob) return false; + BitChart.downloadBlob(fileName || 'chart.png', blob); + return true; + } + + // Returns the standalone SVG markup instead of downloading it, so the caller can embed, + // upload or store the picture itself. + public static toSvgString(element: HTMLElement, background: string | null) { + return BitChart.serialize(element, background); + } + + // Returns the rasterized chart as a data URL (the same picture exportPng downloads). + public static async toDataUrl(element: HTMLElement, mimeType: string, scale: number, background: string | null) { + const canvas = await BitChart.rasterize(element, scale, background); + if (!canvas) return null; + return canvas.toDataURL(mimeType || 'image/png'); + } + + public static downloadText(fileName: string, content: string, mimeType: string) { + const type = mimeType || 'text/plain;charset=utf-8'; + // Spreadsheets read a CSV as the local codepage unless it opens with a byte order mark, so a + // file of Japanese or Persian labels arrives as mojibake without one. + const parts = type.indexOf('text/csv') === 0 ? ['', content] : [content]; + BitChart.downloadBlob(fileName || 'chart.csv', new Blob(parts, { type })); + } + + private static downloadBlob(fileName: string, blob: Blob) { + const url = URL.createObjectURL(blob); + const anchor = document.createElement('a'); + anchor.href = url; + anchor.download = fileName; + document.body.appendChild(anchor); + anchor.click(); + document.body.removeChild(anchor); + setTimeout(() => URL.revokeObjectURL(url), 0); + } } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChartJsRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChartJsRuntimeExtensions.cs index 419c858a8a..d623dec943 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChartJsRuntimeExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChartJsRuntimeExtensions.cs @@ -6,9 +6,10 @@ internal static class BitChartJsRuntimeExtensions { public static ValueTask BitChartObserve(this IJSRuntime jsRuntime, ElementReference element, - DotNetObjectReference dotnetObj) + DotNetObjectReference dotnetObj, + bool responsive) { - return jsRuntime.InvokeAsync("BitBlazorUI.BitChart.observe", element, dotnetObj); + return jsRuntime.InvokeAsync("BitBlazorUI.BitChart.observe", element, dotnetObj, responsive); } // The zoom payload is only ever constructed (never read) from C#, so without this hint the @@ -22,4 +23,32 @@ public static ValueTask BitChartRegister(this IJSRuntime jsR { return jsRuntime.InvokeAsync("BitBlazorUI.BitChart.register", element, dotnetObj, options); } + + public static ValueTask BitChartExportSvg(this IJSRuntime jsRuntime, ElementReference element, + string fileName, string? background) + { + return jsRuntime.InvokeAsync("BitBlazorUI.BitChart.exportSvg", element, fileName, background); + } + + public static ValueTask BitChartExportPng(this IJSRuntime jsRuntime, ElementReference element, + string fileName, double scale, string? background) + { + return jsRuntime.InvokeAsync("BitBlazorUI.BitChart.exportPng", element, fileName, scale, background); + } + + public static ValueTask BitChartToSvgString(this IJSRuntime jsRuntime, ElementReference element, string? background) + { + return jsRuntime.InvokeAsync("BitBlazorUI.BitChart.toSvgString", element, background); + } + + public static ValueTask BitChartToDataUrl(this IJSRuntime jsRuntime, ElementReference element, + string mimeType, double scale, string? background) + { + return jsRuntime.InvokeAsync("BitBlazorUI.BitChart.toDataUrl", element, mimeType, scale, background); + } + + public static ValueTask BitChartDownloadText(this IJSRuntime jsRuntime, string fileName, string content, string mimeType) + { + return jsRuntime.InvokeVoidAsync("BitBlazorUI.BitChart.downloadText", fileName, content, mimeType); + } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChartSvgPrimitive.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChartSvgPrimitive.razor index 4cc7f041e6..d786a00cfd 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChartSvgPrimitive.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChartSvgPrimitive.razor @@ -5,62 +5,110 @@ case BitChartSvgLine l: + stroke-dasharray="@l.Dash" transform="@l.Transform" class="@l.CssClass"> + @if (!string.IsNullOrEmpty(l.Title)) { @l.Title } + break; case BitChartSvgRect r: + opacity="@BitChartSvg.N(r.Opacity)" transform="@r.Transform" class="@r.CssClass"> @if (!string.IsNullOrEmpty(r.Title)) { @r.Title } break; case BitChartSvgCircle c: + stroke="@c.Stroke" stroke-width="@BitChartSvg.N(c.StrokeWidth)" opacity="@BitChartSvg.N(c.Opacity)" + transform="@c.Transform" class="@c.CssClass"> + @if (!string.IsNullOrEmpty(c.Title)) { @c.Title } + break; case BitChartSvgPath p: + stroke-dasharray="@p.Dash" stroke-dashoffset="@(p.DashOffset != 0 ? BitChartSvg.N(p.DashOffset) : null)" + stroke-linecap="@p.LineCap" stroke-linejoin="@p.LineJoin" + opacity="@BitChartSvg.N(p.Opacity)" transform="@p.Transform" + class="@PathClass(p)" + pathLength="@(p.AnimateDraw ? "1" : null)"> + @if (!string.IsNullOrEmpty(p.Title)) { @p.Title } + break; case BitChartSvgPolygon poly: @if (poly.Closed) { + stroke-width="@BitChartSvg.N(poly.StrokeWidth)" stroke-linejoin="round" + opacity="@BitChartSvg.N(poly.Opacity)" transform="@poly.Transform" class="@poly.CssClass"> + @if (!string.IsNullOrEmpty(poly.Title)) { @poly.Title } + } else { + stroke-width="@BitChartSvg.N(poly.StrokeWidth)" opacity="@BitChartSvg.N(poly.Opacity)" + transform="@poly.Transform" class="@poly.CssClass"> + @if (!string.IsNullOrEmpty(poly.Title)) { @poly.Title } + } break; case BitChartSvgText t: - @((MarkupString)BuildText(t)) + @RenderText(t) break; } @code { [Parameter, EditorRequired] public BitChartSvgNode Node { get; set; } = default!; + // An animation class is added to the path's own class rather than replacing it, so a path that + // both animates in and carries a class of its own keeps both. + private static string? PathClass(BitChartSvgPath p) + { + string? anim = p.AnimateDraw ? "bit-cht-draw" : p.AnimateFade ? "bit-cht-fade" : null; + if (anim is null) return p.CssClass; + return string.IsNullOrEmpty(p.CssClass) ? anim : $"{p.CssClass} {anim}"; + } + private static string PolyPoints(BitChartSvgPolygon p) => string.Join(" ", p.Points.Select(pt => $"{BitChartSvg.N(pt.X)},{BitChartSvg.N(pt.Y)}")); - private static string BuildText(BitChartSvgText t) + // "text" is a reserved tag name in Razor markup, so the SVG text element is emitted through the + // render tree directly. Values go through AddAttribute/AddContent, which encode them - unlike the + // hand-built markup string this used to be. + private static RenderFragment RenderText(BitChartSvgText t) => builder => + { + builder.OpenElement(0, "text"); + builder.AddAttribute(1, "x", BitChartSvg.N(t.X)); + builder.AddAttribute(2, "y", BitChartSvg.N(t.Y)); + builder.AddAttribute(3, "fill", t.Fill); + builder.AddAttribute(4, "font-family", t.FontFamily); + builder.AddAttribute(5, "font-size", BitChartSvg.N(t.FontSize)); + builder.AddAttribute(6, "font-weight", t.FontWeight); + builder.AddAttribute(7, "font-style", t.FontStyle); + builder.AddAttribute(8, "text-anchor", t.Anchor); + builder.AddAttribute(9, "dominant-baseline", t.Baseline); + builder.AddAttribute(10, "opacity", BitChartSvg.N(t.Opacity)); + if (TextTransform(t) is { } tr) builder.AddAttribute(11, "transform", tr); + if (!string.IsNullOrEmpty(t.CssClass)) builder.AddAttribute(12, "class", t.CssClass); + builder.AddContent(13, t.Text); + if (!string.IsNullOrEmpty(t.Title)) + { + builder.OpenElement(14, "title"); + builder.AddContent(15, t.Title); + builder.CloseElement(); + } + builder.CloseElement(); + }; + + private static string? TextTransform(BitChartSvgText t) { - string transform = t.Rotation != 0 - ? $" transform=\"rotate({BitChartSvg.N(t.Rotation)} {BitChartSvg.N(t.X)} {BitChartSvg.N(t.Y)})\"" - : ""; - string content = System.Net.WebUtility.HtmlEncode(t.Text); - return $"{content}"; + string? rot = t.Rotation != 0 + ? $"rotate({BitChartSvg.N(t.Rotation)} {BitChartSvg.N(t.X)} {BitChartSvg.N(t.Y)})" + : null; + return string.IsNullOrEmpty(t.Transform) ? rot : string.IsNullOrEmpty(rot) ? t.Transform : $"{t.Transform} {rot}"; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDataLabelOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDataLabelOptions.cs index e7af6d603d..0c35424324 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDataLabelOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDataLabelOptions.cs @@ -1,10 +1,10 @@ namespace Bit.BlazorUI; -/// Data label plugin options (renders values on the chart). +/// Data label plugin options (renders the values on the chart itself). public sealed class BitChartDataLabelOptions { public bool Display { get; set; } - public string Color { get; set; } = "#333"; + public string Color { get; set; } = "var(--bit-clr-fg-pri, #1A1A1A)"; public BitChartFont Font { get; set; } = new(); /// Simple value formatter. public Func? Formatter { get; set; } @@ -12,13 +12,26 @@ public sealed class BitChartDataLabelOptions public Func? FormatterCtx { get; set; } /// Per-element display predicate (value, datasetIndex, dataIndex) => show. public Func? DisplayFn { get; set; } - /// Anchor of the label relative to the element (start = baseline, center, end = tip). - public BitChartAlign Anchor { get; set; } = BitChartAlign.Center; + /// + /// Where the label sits relative to the element: at the baseline + /// end, in the middle, at the tip. + /// + public BitChartAlign Anchor { get; set; } = BitChartAlign.End; + /// + /// Which side of the anchor the label is drawn on: pulls it inside + /// the element, pushes it outside, + /// centers it on the anchor. + /// + public BitChartAlign Align { get; set; } = BitChartAlign.End; + /// Extra distance (px) between the anchor and the label. + public double Offset { get; set; } = 4; + /// Also draw labels on line/scatter/radar point markers (bars and arcs always get them). + public bool ShowOnPoints { get; set; } = true; /// Optional background color drawn behind the label. public string? BackgroundColor { get; set; } /// Corner radius of the label background. public double BorderRadius { get; set; } = 3; - /// BitChartPadding inside the label background. + /// Padding inside the label background. public double Padding { get; set; } = 2; /// Rotation of the label text in degrees. public double Rotation { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDataset.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDataset.cs index 8859c0d46f..e45cafbf0e 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDataset.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDataset.cs @@ -19,6 +19,22 @@ public sealed class BitChartDataset /// Point data for scatter/bubble charts. When set, takes precedence over . public List? Points { get; set; } + /// + /// Per-index uncertainty, drawn as a whisker through the value: a bar's tip, a line or scatter + /// point, each with a cap at both ends. A null entry leaves that point without one. The interval is + /// also named in the tooltip. Cartesian charts only. + /// + public List? ErrorData { get; set; } + + /// Color of the error-bar whisker. When null it follows the primary foreground token. + public string? ErrorBarColor { get; set; } + + /// Thickness of the error-bar whisker and its caps. + public double ErrorBarWidth { get; set; } = 1.5; + + /// Full width of the caps at the ends of an error bar. Zero draws a bare whisker. + public double ErrorBarCapWidth { get; set; } = 8; + /// Optional per-dataset type override for mixed charts. public BitChartType? Type { get; set; } @@ -29,11 +45,22 @@ public sealed class BitChartDataset public BitChartFillPattern? BackgroundPattern { get; set; } public string? BorderColor { get; set; } public List? BorderColors { get; set; } - public double BorderWidth { get; set; } = 1; + /// + /// Border/line thickness. When null a per-type default applies: + /// for lines and radar, for arcs, and for bars + /// unless a border color was supplied (then 1). + /// + public double? BorderWidth { get; set; } + + /// Fill color used while the element is hovered (bars and arcs). public string? HoverBackgroundColor { get; set; } + /// Border color used while the element is hovered (bars and arcs). public string? HoverBorderColor { get; set; } + /// Border width used while the element is hovered (bars and arcs). public double? HoverBorderWidth { get; set; } + /// Extra pixels a hovered arc is pushed out from the center (pie/doughnut/polar area). + public double HoverOffset { get; set; } = 6; // ---- BitChartScriptable options (evaluated per element; take precedence over the constants above) ---- /// BitChartScriptable background color: ctx => color. @@ -58,12 +85,14 @@ public sealed class BitChartDataset public BitChartGradientBase? FillGradient { get; set; } /// Target dataset index when is . public int? FillTargetIndex { get; set; } - /// Bezier curve tension (0 = straight lines). - public double Tension { get; set; } + /// Bezier curve tension (0 = straight lines). Falls back to when unset. + public double? Tension { get; set; } /// Cubic interpolation mode. avoids overshoot. public BitChartCubicInterpolationMode CubicInterpolationMode { get; set; } = BitChartCubicInterpolationMode.Default; public BitChartSteppedLine Stepped { get; set; } = BitChartSteppedLine.False; public List? BorderDash { get; set; } + /// Offset (px) of the first dash in . + public double BorderDashOffset { get; set; } public string BorderJoinStyle { get; set; } = "round"; public string BorderCapStyle { get; set; } = "round"; public bool ShowLine { get; set; } = true; @@ -74,13 +103,17 @@ public sealed class BitChartDataset public double? FillValue { get; set; } // ---- Point element options ---- - public double PointRadius { get; set; } = 3; + /// Marker radius. Zero hides the marker but keeps the point hoverable; null falls back to + /// . + public double? PointRadius { get; set; } public double PointHoverRadius { get; set; } = 4; public double PointBorderWidth { get; set; } = 1; public string? PointBackgroundColor { get; set; } public string? PointBorderColor { get; set; } public BitChartPointStyle PointStyle { get; set; } = BitChartPointStyle.Circle; - /// Pixel radius around a point that still counts as a hit for hover/tooltip. + /// Rotation of the point marker in degrees. + public double PointRotation { get; set; } + /// Extra pixel radius around a point that still counts as a hit for hover/tooltip. public double HitRadius { get; set; } = 1; /// Point fill color when hovered (falls back to ). public string? PointHoverBackgroundColor { get; set; } @@ -94,18 +127,40 @@ public sealed class BitChartDataset public double? MaxBarThickness { get; set; } public double BarPercentage { get; set; } = 0.9; public double CategoryPercentage { get; set; } = 0.8; + /// + /// Corner radius in pixels. On a bar it rounds the corners away from the baseline (see + /// ); on a pie, doughnut or polar-area arc it rounds the arc's own + /// corners, mirroring Chart.js's shared borderRadius. + /// public double BorderRadius { get; set; } /// Optional per-corner bar radius. When set, overrides . public BitChartBorderRadiusCorners? BorderRadiusCorners { get; set; } /// Pixels to grow each bar by to avoid anti-aliasing gaps between stacked bars. public double? InflateAmount { get; set; } + /// Minimum bar length in pixels, so very small values stay visible. + public double? MinBarLength { get; set; } + /// The value bars start from. Defaults to zero clamped into the axis range. + public double? Base { get; set; } + /// When false the dataset is not grouped with the other bar datasets and keeps the full band. + public bool Grouped { get; set; } = true; + /// When true, null values leave no gap: the remaining bars in the group expand to fill the band. + public bool SkipNull { get; set; } /// Which bar edge omits its border. Default skips the baseline edge. public BitChartBorderSkipped BorderSkipped { get; set; } = BitChartBorderSkipped.Start; // ---- Arc (pie/doughnut/polar) element options ---- + /// Pixels every arc of this dataset is pushed out from the center. public double Offset { get; set; } + /// Angular gap (in pixels along the outer edge) left between neighbouring arcs. public double SpacingArc { get; set; } + /// + /// Relative thickness of this dataset's ring in a multi-dataset pie or doughnut. The available + /// radius is shared out in proportion to the weights, so a dataset with weight 2 gets a band twice + /// as thick as one left at the default of 1. Mirrors Chart.js's arc dataset weight. + /// + public double Weight { get; set; } = 1; + // ---- Axis assignment / stacking / ordering ---- public string XAxisID { get; set; } = "x"; public string YAxisID { get; set; } = "y"; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDecimationOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDecimationOptions.cs index d5af7969ac..7fd5df8a9a 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDecimationOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartDecimationOptions.cs @@ -1,6 +1,10 @@ namespace Bit.BlazorUI; -/// BitChartDecimation (downsampling) options for large line datasets. +/// +/// Downsampling options for large line datasets. Decimation applies to unstacked lines and areas: +/// stacked ones are accumulated index by index across their datasets, so thinning them separately +/// would leave the layers no longer adding up. +/// public sealed class BitChartDecimationOptions { public bool Enabled { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartElementOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartElementOptions.cs index 33a98fa008..2fa93c4661 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartElementOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartElementOptions.cs @@ -1,12 +1,21 @@ namespace Bit.BlazorUI; -/// Default element options, mirroring Chart.js options.elements. +/// +/// Default element options, mirroring Chart.js options.elements. Every value here is the +/// fallback used when the matching dataset property is left unset. +/// public sealed class BitChartElementOptions { + /// Default point radius for datasets that do not set . public double PointRadius { get; set; } = 3; + /// Default bezier tension for datasets that do not set . public double LineTension { get; set; } + /// Default line thickness for line and radar datasets. public double LineBorderWidth { get; set; } = 3; + /// Default bar border thickness (Chart.js draws no bar border by default). public double BarBorderWidth { get; set; } + /// Default arc border thickness for pie/doughnut/polar area. public double ArcBorderWidth { get; set; } = 2; - public string ArcBorderColor { get; set; } = "#fff"; + /// Default arc border color; follows the theme background so arcs separate cleanly. + public string ArcBorderColor { get; set; } = "var(--bit-clr-bg-pri, #fff)"; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartErrorBar.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartErrorBar.cs new file mode 100644 index 0000000000..dcd22045dc --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartErrorBar.cs @@ -0,0 +1,15 @@ +namespace Bit.BlazorUI; + +/// +/// The uncertainty around one data point, drawn as a whisker through it. The two arms are given +/// separately so an asymmetric interval - a confidence band that is not centered on the estimate - +/// can be expressed; assigning a single number gives a symmetric one. +/// +public readonly record struct BitChartErrorBar(double Minus, double Plus) +{ + /// A symmetric interval of either side of the value. + public static implicit operator BitChartErrorBar(double amount) => new(amount, amount); + + /// True when both arms are the same length. + public bool IsSymmetric => Math.Abs(Minus - Plus) < 1e-9; +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartFillMode.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartFillMode.cs index 2c3b40edbc..b293e7caf6 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartFillMode.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartFillMode.cs @@ -3,10 +3,16 @@ namespace Bit.BlazorUI; /// How a line/area dataset fills relative to a baseline. public enum BitChartFillMode { + /// No area fill. None, + /// Fill to zero (clamped into the axis range). Origin, + /// Fill to the low end of the axis. Start, + /// Fill to the high end of the axis. End, + /// Fill to the series stacked below this one. Needs a stacked value axis; without one it + /// behaves like . Stack, /// Fill to another dataset's line (see ). Dataset, diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartInteractionMode.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartInteractionMode.cs index 41669d08db..59a116da2b 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartInteractionMode.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartInteractionMode.cs @@ -3,10 +3,32 @@ namespace Bit.BlazorUI; /// Interaction mode used to determine which items are active on hover. public enum BitChartInteractionMode { + /// + /// Only the single nearest element becomes active. With + /// true that is the element directly under the + /// pointer; with it false the pointer only has to be inside the plot area, and the element nearest + /// to it activates. + /// Nearest, + + /// Every element sharing the hovered element's data index becomes active. Index, + + /// Every element of the hovered element's dataset becomes active. Dataset, + + /// + /// Same as : a single element, which is the one under the pointer only when + /// is true. + /// Point, + + /// Groups by position along the index axis, which for this renderer is the data index. X, + + /// + /// Groups by each element's coordinate along the value axis. This renderer resolves it the same way + /// as , so the hovered element's whole index group becomes active. + /// Y } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartInteractionOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartInteractionOptions.cs index 7ffa66f9e0..2f47fba649 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartInteractionOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartInteractionOptions.cs @@ -1,8 +1,32 @@ namespace Bit.BlazorUI; -/// Interaction options, mirroring Chart.js options.interaction. +/// +/// Interaction options, mirroring Chart.js options.interaction. They decide which elements +/// become active when the pointer moves over the chart, and the tooltip inherits them unless it +/// overrides / . +/// public sealed class BitChartInteractionOptions { + /// How the active element set is derived from the hovered element. public BitChartInteractionMode Mode { get; set; } = BitChartInteractionMode.Nearest; - public bool Intersect { get; set; } = true; + + /// + /// When true the pointer must be directly over an element for it to activate. When false (the + /// default) the chart also reacts anywhere inside the plot area: an invisible hit band per + /// category/x position activates that index, so thin lines and datasets drawn without point + /// markers stay hoverable. + /// + public bool Intersect { get; set; } + + /// Draw a crosshair line through the active index (index-style interactions only). + public bool Crosshair { get; set; } = true; + + /// Color of the crosshair line. + public string CrosshairColor { get; set; } = "var(--bit-clr-fg-sec, rgba(0,0,0,0.45))"; + + /// + /// Show the active index in a small chip where the crosshair meets the index axis, so the reader can + /// see which category is being compared without leaving the plot. + /// + public bool CrosshairLabel { get; set; } = true; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartLegendLabelOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartLegendLabelOptions.cs index 79184f235f..de02d099b1 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartLegendLabelOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartLegendLabelOptions.cs @@ -7,6 +7,7 @@ public sealed class BitChartLegendLabelOptions public BitChartFont Font { get; set; } = new(); public double BoxWidth { get; set; } = 40; public double BoxHeight { get; set; } = 12; + /// Gap (px) between legend items. public double Padding { get; set; } = 10; public bool UsePointStyle { get; set; } public BitChartPointStyle PointStyle { get; set; } = BitChartPointStyle.Circle; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartLegendOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartLegendOptions.cs index 832714b7e8..6048bcd09a 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartLegendOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartLegendOptions.cs @@ -11,4 +11,13 @@ public sealed class BitChartLegendOptions public bool OnClickToggle { get; set; } = true; public BitChartLegendLabelOptions Labels { get; set; } = new(); public string? Title { get; set; } + + /// + /// Caps the legend's height in pixels and lets it scroll past that. A chart of twenty series would + /// otherwise give most of its box to the legend; with a cap the plot keeps its space and the + /// remaining entries stay one scroll away rather than pushed off the chart. + /// + public double? MaxHeight { get; set; } + /// Keeps only the items this predicate accepts, mirroring Chart.js legend.labels.filter. + public Func? Filter { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartOptions.cs index 17bd30cdb3..69fcc68acb 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartOptions.cs @@ -12,6 +12,15 @@ public sealed class BitChartOptions public BitChartIndexAxis IndexAxis { get; set; } = BitChartIndexAxis.X; + /// + /// Draws the chart as a sparkline: every piece of chrome around the data - axes, grid lines, tick + /// labels, legend, title and subtitle - is dropped so the series fills the whole box. It is a + /// presentation switch only: nothing is removed from the data, so tooltips, keyboard navigation and + /// the screen-reader table still describe the full series. Meant for the small inline trend charts + /// that sit inside a KPI tile or a table cell. + /// + public bool Sparkline { get; set; } + public BitChartLayoutOptions Layout { get; set; } = new(); public BitChartInteractionOptions Interaction { get; set; } = new(); public BitChartAnimationOptions Animation { get; set; } = new(); @@ -19,9 +28,18 @@ public sealed class BitChartOptions public BitChartPluginOptions Plugins { get; set; } = new(); public BitChartZoomOptions Zoom { get; set; } = new(); - /// Named scales, keyed by id (e.g. "x", "y", "r", "y2"). + /// Named scales, keyed by id (e.g. "x", "y", "r", "y2"). Missing scales are created on the + /// fly by the renderer without mutating this dictionary, so the same options instance can safely be + /// shared between charts of different types. public Dictionary Scales { get; set; } = new(); + /// + /// Culture used to format every number and date the chart renders (tick labels, tooltips and data + /// labels). When null the invariant culture is used, so output stays stable regardless of the + /// thread culture. Set it to CultureInfo.CurrentCulture to follow the user's locale. + /// + public System.Globalization.CultureInfo? Culture { get; set; } + // ---- Doughnut / pie / polar specific ---- /// Inner radius as a percentage string for doughnut charts (0-100). public double CutoutPercentage { get; set; } = 50; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartPosition.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartPosition.cs index d4411c2c61..d253820276 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartPosition.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartPosition.cs @@ -7,6 +7,13 @@ public enum BitChartPosition Left, Bottom, Right, + + /// + /// Cartesian axes only: draw the axis where the other one reads zero instead of along an edge, so it + /// costs no layout space. Legends and titles have no center placement and fall back to the top. + /// Center, + + /// Reserved. Nothing places itself here yet; it falls back to the default side. Chart } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartScaleOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartScaleOptions.cs index bf5a1d360a..6135d8088e 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartScaleOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartScaleOptions.cs @@ -22,9 +22,15 @@ public sealed class BitChartScaleOptions /// When stacked, normalize each category to 100% (percentage stack). public bool Stacked100 { get; set; } - /// BitChartPadding (fraction of a step) applied at the ends of a category axis. + /// Padding (half a step) applied at the ends of a category axis. public bool Offset { get; set; } + /// + /// When true (the default) the tick count is additionally capped by how many labels actually fit + /// along the axis, so short charts do not end up with overlapping tick labels. + /// + public bool AutoSkipTicks { get; set; } = true; + public BitChartGridOptions Grid { get; set; } = new(); public BitChartTickOptions Ticks { get; set; } = new(); public BitChartScaleTitleOptions Title { get; set; } = new(); @@ -43,7 +49,7 @@ public sealed class BitChartScaleOptions /// Show a filled backdrop behind radial tick labels. public bool ShowLabelBackdrop { get; set; } = true; /// Backdrop color for radial tick labels. - public string BackdropColor { get; set; } = "rgba(255,255,255,0.75)"; + public string BackdropColor { get; set; } = "var(--bit-clr-bg-pri, #fff)"; // ---- Time scale ---- /// The unit for a time axis. Auto picks a sensible unit from the data range. diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartScriptable.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartScriptable.cs deleted file mode 100644 index ba773b90c0..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartScriptable.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Bit.BlazorUI; - -/// -/// A value that is either a constant or a function of . -/// Provides implicit conversions so existing constant assignments keep working while also -/// accepting a scriptable function, mirroring Chart.js scriptable options. -/// -/// The resolved value type. -public readonly struct BitChartScriptable -{ - private readonly T? _constant; - private readonly Func? _fn; - - public BitChartScriptable(T? constant) { _constant = constant; _fn = null; } - public BitChartScriptable(Func fn) { _fn = fn; _constant = default; } - - public bool HasValue => _fn is not null || _constant is not null; - - /// Resolves the value for the given context (function takes precedence). - public T? Resolve(BitChartScriptableContext ctx) => _fn is not null ? _fn(ctx) : _constant; - - public static implicit operator BitChartScriptable(T value) => new(value); - public static implicit operator BitChartScriptable(Func fn) => new(fn); -} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartTickOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartTickOptions.cs index 90945508e1..1a40ef3a5b 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartTickOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartTickOptions.cs @@ -18,11 +18,19 @@ public sealed class BitChartTickOptions public double MinRotation { get; set; } /// Tick label alignment relative to the tick (start/center/end). public BitChartAlign Align { get; set; } = BitChartAlign.Center; + /// Extra pixel shift of the tick label along the axis, mirroring Chart.js ticks.labelOffset. + public double LabelOffset { get; set; } /// Render value-axis tick labels inside the chart area. public bool Mirror { get; set; } + /// + /// Drop labels that would not fit. Category axes skip whole labels; value axes reduce the tick count + /// to what the axis length can show without the labels colliding. + /// public bool AutoSkip { get; set; } = true; /// Optional formatting callback applied to each numeric/category tick value. public Func? Callback { get; set; } + /// Standard or custom .NET numeric format string used for numeric tick labels (e.g. "N0", "P1", "C"). + public string? Format { get; set; } public string? Prefix { get; set; } public string? Suffix { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartTooltipOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartTooltipOptions.cs index d8db8c42ef..d152b77ebf 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartTooltipOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartTooltipOptions.cs @@ -4,8 +4,13 @@ namespace Bit.BlazorUI; public sealed class BitChartTooltipOptions { public bool Enabled { get; set; } = true; - public BitChartInteractionMode Mode { get; set; } = BitChartInteractionMode.Nearest; - public bool Intersect { get; set; } = true; + + /// Overrides for the tooltip only. + public BitChartInteractionMode? Mode { get; set; } + + /// Overrides for the tooltip only. + public bool? Intersect { get; set; } + /// Where the tooltip is anchored when multiple items are active. public BitChartTooltipPositioner Position { get; set; } = BitChartTooltipPositioner.Average; public string BackgroundColor { get; set; } = "rgba(0,0,0,0.8)"; @@ -16,6 +21,13 @@ public sealed class BitChartTooltipOptions public BitChartFont BodyFont { get; set; } = new(); public BitChartFont FooterFont { get; set; } = new() { Weight = "bold" }; public double Padding { get; set; } = 6; + + /// + /// Caps the tooltip's width in pixels and wraps its text at that point. Without one the box stays on + /// a single line per row, which is right for a value but wrong for a sentence, so a callback that + /// returns prose wants a width here. + /// + public double? MaxWidth { get; set; } public double CornerRadius { get; set; } = 6; public bool DisplayColors { get; set; } = true; /// Render the color swatch using the dataset point style instead of a square. @@ -24,6 +36,10 @@ public sealed class BitChartTooltipOptions public string? BorderColor { get; set; } /// Border width of the tooltip box. public double BorderWidth { get; set; } + /// Draw a caret (arrow) pointing at the anchored element. Chart.js draws one by default. + public bool Caret { get; set; } = true; + /// Size of the caret in pixels. + public double CaretSize { get; set; } = 6; /// Text alignment of the title (left/center/right). public BitChartAlign TitleAlign { get; set; } = BitChartAlign.Start; /// Text alignment of the body (left/center/right). @@ -32,4 +48,8 @@ public sealed class BitChartTooltipOptions public BitChartTooltipCallbacks Callbacks { get; set; } = new(); /// Optional label formatter: (datasetLabel, value) => text. Shorthand for Callbacks.Label. public Func? LabelFormatter { get; set; } + /// Filters which active items are listed, mirroring Chart.js tooltip.filter. + public Func? Filter { get; set; } + /// Sorts the listed items, mirroring Chart.js tooltip.itemSort. + public Comparison? ItemSort { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartZoomOptions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartZoomOptions.cs index bf94e52f2b..ed394ecad5 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartZoomOptions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Models/BitChartZoomOptions.cs @@ -12,8 +12,17 @@ public sealed class BitChartZoomOptions public bool DragZoom { get; set; } /// Fill color of the drag-zoom selection box. public string DragBoxColor { get; set; } = "rgba(54,162,235,0.2)"; + /// Border color of the drag-zoom selection box. + public string DragBoxBorderColor { get; set; } = "rgba(54,162,235,0.8)"; /// Axis/axes affected by zoom and pan. public BitChartZoomMode Mode { get; set; } = BitChartZoomMode.X; /// Wheel zoom sensitivity (fraction per wheel notch). public double Speed { get; set; } = 0.15; + /// + /// When true (the default) zooming and panning stay inside the data range, so the chart can never + /// be dragged into empty space or zoomed out past the full series. + /// + public bool LimitToData { get; set; } = true; + /// Smallest visible span, as a fraction of the full data range (guards against zooming in forever). + public double MinRangeFraction { get; set; } = 0.001; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartAxisScale.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartAxisScale.cs index ddbf872d3a..775920f1e6 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartAxisScale.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartAxisScale.cs @@ -21,6 +21,14 @@ public sealed class BitChartAxisScale /// Computed label rotation in degrees (auto-fit for category axes). public double LabelRotation { get; set; } + /// Culture used to format tick labels. Defaults to the invariant culture. + public CultureInfo Culture { get; set; } = CultureInfo.InvariantCulture; + + /// The pixel range currently mapped onto, as last passed to . + public double PixelStart => _pixelStart; + /// + public double PixelEnd => _pixelEnd; + private double _pixelStart; private double _pixelEnd; private readonly List? _categories; @@ -96,6 +104,26 @@ public void SetPixelRange(double start, double end) BuildTicks(); } + /// + /// The most ticks that fit along the axis without their labels colliding. Value axes read labels + /// perpendicular to the axis, so the limit follows the line height; along a horizontal axis it + /// follows a conservative label width instead. + /// + private int FitTickLimit(int requested) + { + if (!Options.AutoSkipTicks) return requested; + // A single-category axis - or an explicit tick count of one - asks for fewer than the two the + // fit is floored at, and there is nothing to thin out there anyway. + if (requested < 2) return requested; + double length = Math.Abs(_pixelEnd - _pixelStart); + if (length <= 0) return requested; + double perTick = Horizontal + ? Math.Max(24, Options.Ticks.Font.Size * 3.2) // room for a short numeric label + : Options.Ticks.Font.LineHeightPx * 1.6; // room for one line of text + int fits = (int)Math.Floor(length / perTick) + 1; + return Math.Clamp(fits, 2, requested); + } + public double PixelFor(double value) { double t = NormalizedPosition(value); @@ -164,8 +192,8 @@ private void BuildTicks() private void BuildTimeTicks() { - int maxTicks = Options.Ticks.Count ?? Options.Ticks.MaxTicksLimit ?? 11; - foreach (var (value, label) in BitChartTimeAxis.Ticks(Min, Max, Options.TimeUnit, Options.TimeFormat, maxTicks)) + int maxTicks = FitTickLimit(Options.Ticks.Count ?? Options.Ticks.MaxTicksLimit ?? 11); + foreach (var (value, label) in BitChartTimeAxis.Ticks(Min, Max, Options.TimeUnit, Options.TimeFormat, maxTicks, Culture)) Ticks.Add(new BitChartAxisTick(value, label, PixelFor(value))); } @@ -177,7 +205,7 @@ private void BuildCategoryTicks() int end = Math.Min(n - 1, (int)Math.Floor(Max + 1e-9)); if (end < start) return; int visible = end - start + 1; - int maxLabels = Options.Ticks.MaxTicksLimit ?? visible; + int maxLabels = FitTickLimit(Options.Ticks.MaxTicksLimit ?? visible); int skip = Options.Ticks.AutoSkip && visible > maxLabels ? (int)Math.Ceiling((double)visible / maxLabels) : 1; for (int i = start; i <= end; i++) { @@ -189,7 +217,7 @@ private void BuildCategoryTicks() private void BuildLinearTicks() { - int maxTicks = Options.Ticks.Count ?? Options.Ticks.MaxTicksLimit ?? 11; + int maxTicks = FitTickLimit(Options.Ticks.Count ?? Options.Ticks.MaxTicksLimit ?? 11); maxTicks = Math.Max(2, maxTicks); double range = Max - Min; @@ -213,12 +241,19 @@ private void BuildLinearTicks() Max = niceMax; } + // A step far smaller than the range (an explicit StepSize of 1 over millions, say) would + // otherwise generate ticks until the browser gives up, so the emitted count is bounded. + int limit = Math.Max(maxTicks * 4, 64); + if ((niceMax - niceMin) / rawStep > limit) + rawStep = (niceMax - niceMin) / limit; + int decimals = DecimalsFor(rawStep); for (double v = niceMin; v <= niceMax + rawStep * 0.5; v += rawStep) { double val = Math.Round(v, 8); if (val < Min - 1e-9 || val > Max + 1e-9) continue; Ticks.Add(new BitChartAxisTick(val, FormatValue(val, decimals), PixelFor(val))); + if (Ticks.Count > limit) break; } } @@ -253,7 +288,8 @@ public string FormatValue(double value, int decimals) if (Options.Ticks.Callback is { } cb) return cb(value, Ticks.Count); if (Options.Ticks.Precision is { } p) decimals = p; - string s = value.ToString("N" + Math.Max(0, decimals), CultureInfo.InvariantCulture); + string format = Options.Ticks.Format ?? "N" + Math.Max(0, decimals); + string s = value.ToString(format, Culture); return $"{Options.Ticks.Prefix}{s}{Options.Ticks.Suffix}"; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartColorUtil.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartColorUtil.cs index 3237a4fae9..9aecbbcae0 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartColorUtil.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartColorUtil.cs @@ -50,6 +50,21 @@ public static string Adjust(string color, double factor) private static int Clamp(int v) => Math.Max(0, Math.Min(255, v)); + /// Expands one hex digit into a byte (the #rgb short form). + private static bool Nibble(char c, out int value) + { + if (!int.TryParse(stackalloc char[] { c }, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out value)) + { + value = 0; + return false; + } + value = value * 17; + return true; + } + + private static bool Byte(ReadOnlySpan pair, out int value) + => int.TryParse(pair, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out value); + public static bool TryParse(string color, out int r, out int g, out int b, out double a) { r = g = b = 0; a = 1; @@ -58,21 +73,27 @@ public static bool TryParse(string color, out int r, out int g, out int b, out d if (color.StartsWith('#')) { - var hex = color[1..]; - if (hex.Length == 3) + // Parsed rather than converted: a stray character in a color string is a typo, not a reason + // for the whole chart to throw out of its render. + var hex = color.AsSpan(1); + if (hex.Length == 3 || hex.Length == 4) { - r = Convert.ToInt32($"{hex[0]}{hex[0]}", 16); - g = Convert.ToInt32($"{hex[1]}{hex[1]}", 16); - b = Convert.ToInt32($"{hex[2]}{hex[2]}", 16); + if (!Nibble(hex[0], out r) || !Nibble(hex[1], out g) || !Nibble(hex[2], out b)) return false; + if (hex.Length == 4) + { + if (!Nibble(hex[3], out var na)) return false; + a = na / 255.0; + } return true; } if (hex.Length == 6 || hex.Length == 8) { - r = Convert.ToInt32(hex.Substring(0, 2), 16); - g = Convert.ToInt32(hex.Substring(2, 2), 16); - b = Convert.ToInt32(hex.Substring(4, 2), 16); + if (!Byte(hex[..2], out r) || !Byte(hex.Slice(2, 2), out g) || !Byte(hex.Slice(4, 2), out b)) return false; if (hex.Length == 8) - a = Convert.ToInt32(hex.Substring(6, 2), 16) / 255.0; + { + if (!Byte(hex.Slice(6, 2), out var ba)) return false; + a = ba / 255.0; + } return true; } return false; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartDataElement.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartDataElement.cs index 3f69e663b8..ef7ea27a0d 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartDataElement.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartDataElement.cs @@ -11,17 +11,15 @@ public sealed class BitChartDataElement /// Hit-test centroid in chart pixel coordinates. public double CenterX { get; init; } public double CenterY { get; init; } - /// Optional shape used when this element is the active/hovered one. + /// + /// The shape drawn on top of this element while it is active (hovered or keyboard-focused). It is + /// precomputed by the renderer with the dataset's hover styling - and with + /// set - so hovering never costs a re-layout. + /// public BitChartSvgNode? HoverShape { get; init; } /// Optional secondary shape drawn with the element (e.g. a bar's skipped-edge border) /// so it animates together with the fill. public BitChartSvgNode? BorderShape { get; init; } - /// Per-element entry animation CSS class (e.g. grow from baseline for bars, pop for points). - public string? EnterAnim { get; init; } - /// Transform origin (in view-box/pixel coordinates) for the entry animation - the bar baseline - /// or the point center. - public double AnimOriginX { get; init; } - public double AnimOriginY { get; init; } /// Primary numeric value of this element (for tooltip templates). public double Value { get; init; } /// Series (dataset) label, for tooltip templates. diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartHitBand.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartHitBand.cs new file mode 100644 index 0000000000..821be4d0bd --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartHitBand.cs @@ -0,0 +1,17 @@ +namespace Bit.BlazorUI; + +/// +/// An invisible rectangle covering one index (category / x position) across the whole plot area. +/// Hovering it activates that index even when the pointer is nowhere near a bar or a point, which is +/// what keeps thin lines and marker-less datasets interactive. Bands are painted underneath the data +/// elements so an element directly under the pointer always wins. +/// +public sealed class BitChartHitBand +{ + public double X { get; init; } + public double Y { get; init; } + public double Width { get; init; } + public double Height { get; init; } + /// The data index this band represents. + public int DataIndex { get; init; } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartLegendModel.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartLegendModel.cs index 668cc98d7b..6af931cb25 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartLegendModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartLegendModel.cs @@ -9,4 +9,6 @@ public sealed class BitChartLegendModel public BitChartLegendLabelOptions Labels { get; set; } = new(); public string? Title { get; set; } public bool OnClickToggle { get; set; } = true; + /// Height cap in pixels past which the legend scrolls. + public double? MaxHeight { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartPointShapes.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartPointShapes.cs index e2e0ae91f7..4013482af0 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartPointShapes.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartPointShapes.cs @@ -5,6 +5,15 @@ namespace Bit.BlazorUI; public static class BitChartPointShapes { public static BitChartSvgNode? Build(BitChartPointStyle style, double x, double y, double r, + string fill, string stroke, double strokeWidth, double rotation = 0) + { + var node = BuildCore(style, x, y, r, fill, stroke, strokeWidth); + if (node is not null && Math.Abs(rotation) > 1e-3) + node.Transform = $"rotate({BitChartSvg.N(rotation)} {BitChartSvg.N(x)} {BitChartSvg.N(y)})"; + return node; + } + + private static BitChartSvgNode? BuildCore(BitChartPointStyle style, double x, double y, double r, string fill, string stroke, double strokeWidth) { switch (style) diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderState.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderState.cs index cf7f448326..16d703af5c 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderState.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderState.cs @@ -1,6 +1,6 @@ namespace Bit.BlazorUI; -/// Mutable interaction state shared with the component (hover + legend toggles). +/// Mutable interaction state shared with the component (legend toggles + zoom ranges). public sealed class BitChartRenderState { /// Datasets hidden via the legend (by dataset index). @@ -9,9 +9,6 @@ public sealed class BitChartRenderState /// Data indices hidden via the legend (pie/doughnut/polarArea). public HashSet HiddenIndices { get; } = new(); - /// The currently hovered element, if any. - public (int Dataset, int Index)? Active { get; set; } - /// Zoom/pan range overrides per axis id (min, max in data coordinates). public Dictionary AxisRanges { get; } = new(); diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Cartesian.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Cartesian.cs index 8e1b7f466c..dab8122748 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Cartesian.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Cartesian.cs @@ -1,4 +1,3 @@ - namespace Bit.BlazorUI; public sealed partial class BitChartRenderer @@ -12,28 +11,46 @@ private void RenderCartesian(BitChartScene scene) // Identify which scale ids are x-axes (datasets' XAxisID plus the default "x"). var xIds = new HashSet(_data.Datasets.Select(d => string.IsNullOrEmpty(d.XAxisID) ? "x" : d.XAxisID)) { "x" }; - var indexScaleOpts = _options.Scales["x"]; + var indexScaleOpts = Scale("x"); bool indexIsCategory = indexScaleOpts.Type == BitChartScaleType.Category; // Value (y) axes used by datasets. var leftAxes = new List(); var rightAxes = new List(); + // Axes drawn at the other axis' zero line instead of along an edge. They cost no layout space, + // which is exactly the point: they live inside the plot. + var centerAxes = new List(); var valueScales = new Dictionary(); + // The raw extent behind each axis, kept so the full range can be recomputed once the axes are + // laid out - a zoomed axis is pinned to its zoom range and cannot report it itself. + var dataExtents = new Dictionary(); - foreach (var (id, so) in _options.Scales) + foreach (var (id, so) in _scales) { if (xIds.Contains(id) || so.Type == BitChartScaleType.RadialLinear) continue; var (mn, mx) = ComputeValueExtent(id); - var scale = new BitChartAxisScale(so, horizontal: !IsVertical); + dataExtents[id] = (mn, mx); + var scale = new BitChartAxisScale(so, horizontal: !IsVertical) { Culture = Culture }; + scale.SetDataRange(mn, mx); if (so.Type != BitChartScaleType.Category && _state.AxisRanges.TryGetValue(id, out var ov)) + { scale.Forced = ov; - scale.SetDataRange(mn, mx); - scale.SetPixelRange(0, 100); // provisional, for tick labels + scale.SetDataRange(mn, mx); + } + // Provisional pixel range spanning the content box: close enough to the final one that + // tick-label measurement (and the fit-based tick limit) reserves the right amount of space. + if (IsVertical) scale.SetPixelRange(area.Bottom, area.Top); + else scale.SetPixelRange(area.Left, area.Right); valueScales[id] = scale; + if (so.Reverse) scene.ReversedAxes.Add(id); if (so.Type != BitChartScaleType.Category) scene.ZoomableAxes.Add(id); - if (!so.Display) continue; - if ((so.Position ?? BitChartPosition.Left) == BitChartPosition.Right) rightAxes.Add(scale); - else leftAxes.Add(scale); + if (!ScaleVisible(so)) continue; + switch (PositionOf(so, IsVertical ? BitChartPosition.Left : BitChartPosition.Bottom)) + { + case BitChartPosition.Right or BitChartPosition.Top: rightAxes.Add(scale); break; + case BitChartPosition.Center: centerAxes.Add(scale); break; + default: leftAxes.Add(scale); break; + } } // X axes ("x" is the primary index scale; others are secondary, point-bound). @@ -44,46 +61,72 @@ private void RenderCartesian(BitChartScene scene) foreach (var id in xIds.OrderBy(s => s == "x" ? 0 : 1)) { - var so = _options.Scales[id]; + var so = Scale(id); BitChartAxisScale xs; if (id == "x" && indexIsCategory) { - xs = new BitChartAxisScale(so, horizontal: IsVertical, categories: _data.Labels); - if (_state.AxisRanges.TryGetValue("x", out var cov)) xs.Forced = cov; + xs = new BitChartAxisScale(so, horizontal: IsVertical, categories: _data.Labels) { Culture = Culture }; + dataExtents[id] = (0, Math.Max(0, _data.Labels.Count - 1)); xs.SetDataRange(0, Math.Max(0, _data.Labels.Count - 1)); + if (_state.AxisRanges.TryGetValue("x", out var cov)) + { + xs.Forced = cov; + xs.SetDataRange(0, Math.Max(0, _data.Labels.Count - 1)); + } } else { var (mn, mx) = id == "x" ? ComputeIndexExtent() : ComputeXExtent(id); - xs = new BitChartAxisScale(so, horizontal: IsVertical); - if (_state.AxisRanges.TryGetValue(id, out var ov)) xs.Forced = ov; + dataExtents[id] = (mn, mx); + xs = new BitChartAxisScale(so, horizontal: IsVertical) { Culture = Culture }; xs.SetDataRange(mn, mx); + if (_state.AxisRanges.TryGetValue(id, out var ov)) + { + xs.Forced = ov; + xs.SetDataRange(mn, mx); + } } - xs.SetPixelRange(0, 100); + if (IsVertical) xs.SetPixelRange(area.Left, area.Right); + else xs.SetPixelRange(area.Top, area.Bottom); xScales[id] = xs; + if (so.Reverse) scene.ReversedAxes.Add(id); scene.ZoomableAxes.Add(id); if (id == "x") indexScale = xs; - if (so.Display) + if (ScaleVisible(so)) { - if ((so.Position ?? BitChartPosition.Bottom) == BitChartPosition.Top) topXAxes.Add(xs); + if (PositionOf(so, BitChartPosition.Bottom) == BitChartPosition.Top) topXAxes.Add(xs); else bottomXAxes.Add(xs); } } // ---- Reserve space for axes ---- - double leftReserve = leftAxes.Sum(a => ReserveValueAxis(a)); - double rightReserve = rightAxes.Sum(a => ReserveValueAxis(a)); + // Which side an axis lives on follows the orientation, not the axis' role: with a vertical + // index axis (horizontal bars) the categories run down the left edge and the values along the + // bottom, so the reservations swap - a side axis needs label *width*, an edge axis needs + // label *height*. + double leftReserve, rightReserve, bottomReserve, topReserve; + if (IsVertical) + { + leftReserve = leftAxes.Sum(ReserveAxisWidth); + rightReserve = rightAxes.Sum(ReserveAxisWidth); - // Auto-rotate category labels on the bottom (x) axis when they don't fit. - if (IsVertical && indexIsCategory && indexScaleOpts.Display && indexScaleOpts.Ticks.Display) + // Auto-rotate category labels on the bottom (x) axis when they don't fit. + if (indexIsCategory && ScaleVisible(indexScaleOpts) && indexScaleOpts.Ticks.Display) + indexScale.LabelRotation = ComputeIndexLabelRotation(indexScale, area.Width - leftReserve - rightReserve); + + bottomReserve = bottomXAxes.Sum(ReserveAxisHeight); + topReserve = topXAxes.Sum(ReserveAxisHeight); + } + else { - double availW = area.Width - leftReserve - rightReserve; - indexScale.LabelRotation = ComputeIndexLabelRotation(indexScale, availW); + leftReserve = ReserveAxisWidth(indexScale); + rightReserve = 0; + // "left"/"right" name the near/far edge, which here is the bottom and the top, so each + // stack reserves height on its own side. + bottomReserve = leftAxes.Sum(ReserveAxisHeight); + topReserve = rightAxes.Sum(ReserveAxisHeight); } - double bottomReserve = IsVertical ? bottomXAxes.Sum(ReserveIndexAxis) : ReserveIndexAxis(indexScale); - double topReserve = IsVertical ? topXAxes.Sum(ReserveIndexAxis) : 0; - var plot = new BitChartArea(area.Left + leftReserve, area.Top + topReserve, area.Right - rightReserve, area.Bottom - bottomReserve); // ---- Final pixel ranges ---- @@ -98,24 +141,31 @@ private void RenderCartesian(BitChartScene scene) foreach (var s in valueScales.Values) s.SetPixelRange(plot.Left, plot.Right); } + // ---- Full (un-zoomed) ranges, for the zoom clamp ---- + // Recorded only now: building the ticks nice-rounds a linear axis outwards, so anything read + // off a scale before it is laid out is narrower than what the axis displays - and clamping a + // gesture to that would snap the first zoom-out inside the visible range with no way back. + foreach (var (id, s) in xScales) RecordDataRange(id, s); + foreach (var (id, s) in valueScales) RecordDataRange(id, s); + // ---- Grid + axes ---- - DrawGrid(scene, plot, indexScale, valueScales, leftAxes, rightAxes); + DrawGrid(scene, plot, indexScale, leftAxes, rightAxes, centerAxes); // Secondary x axes (display only; stacked outside the plot, no chart-area grid). if (IsVertical) { - double belowOffset = ReserveIndexAxis(indexScale); + double belowOffset = ReserveAxisHeight(indexScale); foreach (var xs in bottomXAxes) { if (ReferenceEquals(xs, indexScale)) continue; DrawSecondaryXAxis(scene, plot, xs, plot.Bottom + belowOffset, atBottom: true); - belowOffset += ReserveIndexAxis(xs); + belowOffset += ReserveAxisHeight(xs); } double aboveOffset = 0; foreach (var xs in topXAxes) { if (ReferenceEquals(xs, indexScale)) continue; - aboveOffset += ReserveIndexAxis(xs); + aboveOffset += ReserveAxisHeight(xs); DrawSecondaryXAxis(scene, plot, xs, plot.Top - aboveOffset, atBottom: false); } } @@ -123,8 +173,18 @@ private void RenderCartesian(BitChartScene scene) scene.PlotArea = plot; scene.AxisRanges["x"] = (indexScale.Min, indexScale.Max); - foreach (var (id, s) in xScales) scene.AxisRanges[id] = (s.Min, s.Max); - foreach (var (id, s) in valueScales) scene.AxisRanges[id] = (s.Min, s.Max); + foreach (var (id, s) in xScales) + { + scene.AxisRanges[id] = (s.Min, s.Max); + // An index axis always starts at the near pixel: left of a vertical chart, top of a horizontal one. + scene.AxisOrientations[id] = (IsVertical, false); + } + foreach (var (id, s) in valueScales) + { + scene.AxisRanges[id] = (s.Min, s.Max); + // A vertical value axis is the one drawn bottom-up, so its minimum sits at the far pixel. + scene.AxisOrientations[id] = (!IsVertical, IsVertical); + } var ctx = new BitChartPluginContext { @@ -134,13 +194,32 @@ private void RenderCartesian(BitChartScene scene) IsCartesian = true, IndexScale = indexScale, ValueScales = valueScales, - IndexIsCategory = indexIsCategory + HiddenDatasets = _state.HiddenDatasets, + IndexIsCategory = indexIsCategory, + IndexCentered = HasBars() }; foreach (var plugin in _options.Plugins.Custom) plugin.BeforeDatasetsDraw(ctx); + // A zoomed axis is pinned to its zoom range, so its full range is read off a scratch scale + // laid out exactly as it is but without the zoom. A category axis is never rounded, so its + // extent is already the answer. + void RecordDataRange(string id, BitChartAxisScale s) + { + if (s.Forced is null) { scene.DataRanges[id] = (s.Min, s.Max); return; } + var ext = dataExtents[id]; + if (s.Type == BitChartScaleType.Category) { scene.DataRanges[id] = ext; return; } + var probe = new BitChartAxisScale(s.Options, s.Horizontal) { Culture = Culture }; + probe.SetDataRange(ext.Min, ext.Max); + probe.SetPixelRange(s.PixelStart, s.PixelEnd); + scene.DataRanges[id] = (probe.Min, probe.Max); + } + BitChartAxisScale XScaleFor(BitChartDataset ds) => xScales.TryGetValue(string.IsNullOrEmpty(ds.XAxisID) ? "x" : ds.XAxisID, out var s) ? s : indexScale; + BitChartAxisScale ValueScaleFor(BitChartDataset ds) + => valueScales.TryGetValue(ds.YAxisID, out var vs) ? vs : valueScales.Values.First(); + // ---- Datasets (respect Order) ---- var ordered = _data.Datasets .Select((d, i) => (d, i)) @@ -168,7 +247,7 @@ BitChartAxisScale XScaleFor(BitChartDataset ds) { if (IsHidden(i, ds)) continue; var type = EffectiveType(ds); - var vScale = valueScales.TryGetValue(ds.YAxisID, out var vs) ? vs : valueScales.Values.First(); + var vScale = ValueScaleFor(ds); var xScale = XScaleFor(ds); switch (type) { @@ -184,16 +263,81 @@ BitChartAxisScale XScaleFor(BitChartDataset ds) } } + BuildHitBands(scene, plot, indexScale, indexIsCategory, centered); + foreach (var plugin in _options.Plugins.Custom) plugin.AfterDatasetsDraw(ctx); } + /// + /// Builds the invisible per-index hit areas that make hovering work anywhere inside the plot. + /// Skipped when the interaction is configured to require an intersection with a real element. + /// + private void BuildHitBands(BitChartScene scene, BitChartArea plot, BitChartAxisScale indexScale, + bool indexIsCategory, bool centered) + { + if (EffectiveIntersect() || scene.Elements.Count == 0) return; + + // Bands map one index to one slice of the plot, which only makes sense when the datasets share + // that index. Scatter/bubble points are placed by their own x value, so they keep pure + // nearest-element hovering instead. + bool indexAligned = _data.Datasets + .Where((d, i) => !IsHidden(i, d)) + .All(d => EffectiveType(d) is BitChartType.Bar or BitChartType.Line); + if (!indexAligned) return; + + // One band per distinct index, ordered by where that index actually sits along the axis. + // Summed and counted rather than averaged pair by pair, which would weight the last element of + // an index far more heavily than the first. + var sums = new Dictionary(); + foreach (var el in scene.Elements) + { + double c = IsVertical ? el.CenterX : el.CenterY; + var (sum, n) = sums.GetValueOrDefault(el.DataIndex); + sums[el.DataIndex] = (sum + c, n + 1); + } + if (sums.Count is 0 or > 1000) return; + + var ordered = sums.Select(kv => new KeyValuePair(kv.Key, kv.Value.Sum / kv.Value.Count)) + .OrderBy(kv => kv.Value).ToList(); + double lo = IsVertical ? plot.Left : plot.Top; + double hi = IsVertical ? plot.Right : plot.Bottom; + + for (int k = 0; k < ordered.Count; k++) + { + double c = ordered[k].Value; + double prev = k > 0 ? ordered[k - 1].Value : lo - (c - lo); + double next = k < ordered.Count - 1 ? ordered[k + 1].Value : hi + (hi - c); + double start = Math.Max(lo, (prev + c) / 2); + double end = Math.Min(hi, (c + next) / 2); + if (end <= start) continue; + + scene.HitBands.Add(IsVertical + ? new BitChartHitBand { X = start, Y = plot.Top, Width = end - start, Height = plot.Height, DataIndex = ordered[k].Key } + : new BitChartHitBand { X = plot.Left, Y = start, Width = plot.Width, Height = end - start, DataIndex = ordered[k].Key }); + } + } + + /// The interaction mode in effect for hover/tooltip (the tooltip may override the global one). + internal BitChartInteractionMode EffectiveMode() + => _options.Plugins.Tooltip.Mode ?? _options.Interaction.Mode; + + /// Whether the pointer must intersect an element for it to activate. + internal bool EffectiveIntersect() + => _options.Plugins.Tooltip.Intersect ?? _options.Interaction.Intersect; + private BitChartType EffectiveType(BitChartDataset ds) => ds.Type ?? _config.Type; private bool IsHidden(int i, BitChartDataset ds) => ds.Hidden || _state.IsDatasetHidden(i); - private double ReserveIndexAxis(BitChartAxisScale scale) + /// The height an axis drawn along the top or bottom edge needs for its ticks and title. + private double ReserveAxisHeight(BitChartAxisScale scale) { + // Memoized for the same two reasons ReserveAxisWidth is: the label measuring is repeated on + // every later call, and the drawing code has to place the axis at exactly the height the + // layout reserved for it, even though the tick set is rebuilt once the plot area is known. + if (_heightReserve.TryGetValue(scale, out var cached)) return cached; + var o = scale.Options; - if (!o.Display) return 0; + if (!ScaleVisible(o)) return _heightReserve[scale] = 0; double h = 0; if (o.Grid.DrawTicks) h += o.Grid.TickLength; if (o.Ticks.Display) @@ -213,9 +357,12 @@ private double ReserveIndexAxis(BitChartAxisScale scale) } } if (o.Title.Display) h += o.Title.Font.LineHeightPx + o.Title.Padding.Vertical; + _heightReserve[scale] = h; return h; } + private readonly Dictionary _heightReserve = new(); + /// Computes an auto label rotation (degrees) so category labels fit their band width. private static double ComputeIndexLabelRotation(BitChartAxisScale scale, double availWidth) { @@ -229,7 +376,9 @@ private static double ComputeIndexLabelRotation(BitChartAxisScale scale, double if (maxLabel <= 0) return 0; double band = availWidth / Math.Max(1, scale.Ticks.Count); - if (maxLabel <= band * 0.95) return 0; // fits horizontally + // Labels that fit still honour MinRotation, which is how a caller asks for slanted labels + // unconditionally rather than only once they collide. + if (maxLabel <= band * 0.95) return Math.Clamp(tk.MinRotation, 0, tk.MaxRotation); // Rotate just enough so the horizontal footprint fits the band, clamped to limits. double ratio = Math.Clamp(band / maxLabel, -1, 1); @@ -237,48 +386,113 @@ private static double ComputeIndexLabelRotation(BitChartAxisScale scale, double return Math.Clamp(needed, Math.Max(tk.MinRotation, 1), tk.MaxRotation); } - private double ReserveValueAxis(BitChartAxisScale scale) + /// The width an axis drawn along the left or right edge needs for its ticks and title. + private double ReserveAxisWidth(BitChartAxisScale scale) { + // Memoized per render, for two reasons: measuring every tick label of every axis again on each + // of the later calls adds up, and the drawing code must place the axis using exactly the width + // that was reserved for it - even though the tick set is rebuilt once the plot area is known. + if (_widthReserve.TryGetValue(scale, out var cached)) return cached; + var o = scale.Options; - double maxLabel = 0; - if (o.Ticks.Display) - foreach (var t in scale.Ticks) - maxLabel = Math.Max(maxLabel, EstimateTextWidth(t.Label, o.Ticks.Font.Size)); - double w = maxLabel + o.Ticks.Padding; - if (o.Grid.DrawTicks) w += o.Grid.TickLength; - if (o.Title.Display) w += o.Title.Font.LineHeightPx + o.Title.Padding.Horizontal; - return w + 2; + double w; + if (!ScaleVisible(o)) + { + w = 0; + } + else + { + double maxLabel = 0; + if (o.Ticks.Display && !o.Ticks.Mirror) + foreach (var t in scale.Ticks) + maxLabel = Math.Max(maxLabel, EstimateTextWidth(t.Label, o.Ticks.Font.Size)); + w = maxLabel + o.Ticks.Padding; + if (o.Grid.DrawTicks) w += o.Grid.TickLength; + if (o.Title.Display) w += o.Title.Font.LineHeightPx + o.Title.Padding.Horizontal; + w += 2; + } + _widthReserve[scale] = w; + return w; } + private readonly Dictionary _widthReserve = new(); + // ---- extents ---- + /// + /// The stack bucket a dataset belongs to. It has to match how the drawing code groups: bars stack + /// among bars (DrawBars) and lines among lines (DrawStackedAreas), each within its own Stack id. + /// + private string StackKey(BitChartDataset ds) + => (EffectiveType(ds) == BitChartType.Bar ? "bar:" : "line:") + (ds.Stack ?? "default"); + + /// + /// The extent of a percentage-stacked axis. Each category is normalized against the sum of the + /// absolute values in it, so the positive share of a category can never exceed 100 and its negative + /// share can never fall below -100. Taking a flat 0..100 would clip every negative contribution out + /// of the plot, so the real shares are measured and the axis is sized to what is actually drawn. + /// + private (double, double) ComputePercentStackExtent(string axisId) + { + var totals = new Dictionary<(string stack, int index), double>(); + var shares = new Dictionary<(string stack, int index, int sign), double>(); + + for (int d = 0; d < _data.Datasets.Count; d++) + { + var ds = _data.Datasets[d]; + if (ds.YAxisID != axisId || IsHidden(d, ds)) continue; + string key = StackKey(ds); + for (int i = 0; i < ds.Data.Count; i++) + { + if (ds.Data[i] is not { } v) continue; + totals[(key, i)] = totals.GetValueOrDefault((key, i), 0) + Math.Abs(v); + int sign = v >= 0 ? 1 : -1; + shares[(key, i, sign)] = shares.GetValueOrDefault((key, i, sign), 0) + v; + } + } + + double min = 0, max = 0; + foreach (var ((stack, index, _), sum) in shares) + { + double total = totals.GetValueOrDefault((stack, index), 0); + if (total <= 0) continue; + double pct = sum / total * 100; + min = Math.Min(min, pct); + max = Math.Max(max, pct); + } + + // Nothing (or nothing but zeroes) to measure: keep the classic full-height 0..100 axis. + if (min == 0 && max == 0) return (0, 100); + return (min, max); + } + private (double, double) ComputeValueExtent(string axisId) { double min = double.PositiveInfinity, max = double.NegativeInfinity; - var scaleOpts = _options.Scales[axisId]; + var scaleOpts = Scale(axisId); if (scaleOpts.Stacked && scaleOpts.Stacked100) - return (0, 100); + return ComputePercentStackExtent(axisId); if (scaleOpts.Stacked) { - var posSums = new Dictionary(); - var negSums = new Dictionary(); + // Sums are tracked per (stack group, index, sign) so two independent stacks standing side by + // side do not add up into one oversized range. + var sums = new Dictionary<(string stack, int index, int sign), double>(); for (int d = 0; d < _data.Datasets.Count; d++) { var ds = _data.Datasets[d]; if (ds.YAxisID != axisId || IsHidden(d, ds)) continue; + string key = StackKey(ds); for (int i = 0; i < ds.Data.Count; i++) { - double v = ds.Data[i] ?? 0; - var bucket = v >= 0 ? posSums : negSums; - bucket[i] = (bucket.TryGetValue(i, out var s) ? s : 0) + v; + if (ds.Data[i] is not { } v) continue; + int sign = v >= 0 ? 1 : -1; + sums[(key, i, sign)] = sums.GetValueOrDefault((key, i, sign), 0) + v; } } - foreach (var v in posSums.Values) { min = Math.Min(min, v); max = Math.Max(max, v); } - foreach (var v in negSums.Values) { min = Math.Min(min, v); max = Math.Max(max, v); } - if (posSums.Count > 0) min = Math.Min(min, 0); - if (negSums.Count > 0) max = Math.Max(max, 0); + foreach (var v in sums.Values) { min = Math.Min(min, v); max = Math.Max(max, v); } + if (sums.Count > 0) { min = Math.Min(min, 0); max = Math.Max(max, 0); } // Floating bars / point datasets on a stacked axis still contribute their own extent. for (int d = 0; d < _data.Datasets.Count; d++) @@ -305,6 +519,7 @@ private double ReserveValueAxis(BitChartAxisScale scale) foreach (var p in pts) { min = Math.Min(min, p.Y); max = Math.Max(max, p.Y); } else foreach (var v in ds.Data) if (v is { } val) { min = Math.Min(min, val); max = Math.Max(max, val); } + if (ds.Base is { } b) { min = Math.Min(min, b); max = Math.Max(max, b); } } } @@ -321,6 +536,9 @@ private double ReserveValueAxis(BitChartAxisScale scale) if (IsHidden(d, ds)) continue; if (ds.Points is { } pts) foreach (var p in pts) { min = Math.Min(min, p.X); max = Math.Max(max, p.X); } + // A value dataset on a numeric index axis is laid out by its index, so that is its extent. + // Without this it would contribute nothing and the axis would fall back to a bare 0..1. + else if (ds.Data.Count > 0) { min = Math.Min(min, 0); max = Math.Max(max, ds.Data.Count - 1); } } if (double.IsInfinity(min)) { min = 0; max = 1; } return (min, max); diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.CartesianDraw.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.CartesianDraw.cs index ac6b9f0e4f..1381b36532 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.CartesianDraw.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.CartesianDraw.cs @@ -4,27 +4,53 @@ namespace Bit.BlazorUI; public sealed partial class BitChartRenderer { private void DrawGrid(BitChartScene scene, BitChartArea plot, BitChartAxisScale indexScale, - Dictionary valueScales, List leftAxes, List rightAxes) + List leftAxes, List rightAxes, List centerAxes) { bool firstValueGridDrawn = false; - // Value axes. - double leftX = plot.Left; + // Value axes. In a vertical chart they run down the sides and stack outwards by their width; + // with a vertical index axis (horizontal bars) they run along the bottom/top and stack by height. + double near = IsVertical ? plot.Left : plot.Bottom; foreach (var axis in leftAxes) { - DrawValueAxis(scene, plot, axis, leftX, isRight: false, drawArea: !firstValueGridDrawn); + DrawValueAxis(scene, plot, axis, near, isRight: false, drawArea: !firstValueGridDrawn); firstValueGridDrawn = true; - leftX -= ReserveValueAxis(axis); + near += IsVertical ? -ReserveAxisWidth(axis) : ReserveAxisHeight(axis); } - double rightX = plot.Right; + double far = IsVertical ? plot.Right : plot.Top; foreach (var axis in rightAxes) { - DrawValueAxis(scene, plot, axis, rightX, isRight: true, drawArea: false); - rightX += ReserveValueAxis(axis); + DrawValueAxis(scene, plot, axis, far, isRight: true, drawArea: false); + far += IsVertical ? ReserveAxisWidth(axis) : -ReserveAxisHeight(axis); } - // Index axis. - DrawIndexAxis(scene, plot, indexScale); + // Axes pinned to the other axis' zero line, drawn inside the plot. + foreach (var axis in centerAxes) + DrawValueAxis(scene, plot, axis, ZeroLineAlong(indexScale, plot), isRight: false, drawArea: false); + + // Index axis. It too can sit on the value axis' zero line rather than along the edge. + double indexBaseline = PositionOf(indexScale.Options, IsVertical ? BitChartPosition.Bottom : BitChartPosition.Left) == BitChartPosition.Center + ? ZeroLineAcross(leftAxes.Concat(rightAxes).Concat(centerAxes).FirstOrDefault(), plot) + : IsVertical ? plot.Bottom : plot.Left; + DrawIndexAxis(scene, plot, indexScale, indexBaseline); + } + + /// The pixel along the index axis where its value is zero, clamped into the plot. + private double ZeroLineAlong(BitChartAxisScale indexScale, BitChartArea plot) + { + double p = indexScale.Type == BitChartScaleType.Category + ? indexScale.PixelForIndex(0, HasBars()) + : indexScale.PixelFor(0); + return IsVertical ? Math.Clamp(p, plot.Left, plot.Right) : Math.Clamp(p, plot.Top, plot.Bottom); + } + + /// The pixel across the plot where the given value axis reads zero, clamped into the plot. + private double ZeroLineAcross(BitChartAxisScale? valueScale, BitChartArea plot) + { + double fallback = IsVertical ? plot.Bottom : plot.Left; + if (valueScale is null) return fallback; + double p = valueScale.PixelFor(0); + return IsVertical ? Math.Clamp(p, plot.Top, plot.Bottom) : Math.Clamp(p, plot.Left, plot.Right); } private void DrawValueAxis(BitChartScene scene, BitChartArea plot, BitChartAxisScale axis, double axisPos, bool isRight, bool drawArea) @@ -55,18 +81,24 @@ private void DrawValueAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS if (g.DrawTicks) scene.Background.Add(new BitChartSvgLine { - X1 = isRight ? axisPos : axisPos, Y1 = y, + X1 = axisPos, Y1 = y, X2 = isRight ? axisPos + g.TickLength : axisPos - g.TickLength, Y2 = y, Stroke = g.TickColor, StrokeWidth = g.LineWidth }); if (tk.Display) + { + // Mirrored labels sit inside the plot area, on the other side of the axis line. + double lx = tk.Mirror + ? isRight ? axisPos - g.TickLength - tk.Padding : axisPos + g.TickLength + tk.Padding + : isRight ? axisPos + g.TickLength + tk.Padding : axisPos - g.TickLength - tk.Padding; + bool anchorStart = tk.Mirror ? !isRight : isRight; scene.Background.Add(new BitChartSvgText { - X = isRight ? axisPos + g.TickLength + tk.Padding : axisPos - g.TickLength - tk.Padding, - Y = y, Text = tick.Label, Fill = tk.Color, + X = lx, Y = y + TickLabelOffset(tk), Text = tick.Label, Fill = tk.Color, FontFamily = tk.Font.Family, FontSize = tk.Font.Size, FontWeight = tk.Font.Weight, - Anchor = isRight ? "start" : "end", Baseline = "central" + Anchor = anchorStart ? "start" : "end", Baseline = "central" }); + } } else { @@ -85,19 +117,20 @@ private void DrawValueAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS Stroke = Math.Abs(tick.Value) < 1e-9 ? (g.ZeroLineColor ?? g.Color) : g.Color, StrokeWidth = g.LineWidth, Dash = BitChartSvg.Dash(g.BorderDash) }); + int dir = isRight ? -1 : 1; // "right" means the far edge, which is the top here if (g.DrawTicks) scene.Background.Add(new BitChartSvgLine { - X1 = x, Y1 = plot.Bottom, X2 = x, Y2 = plot.Bottom + g.TickLength, + X1 = x, Y1 = axisPos, X2 = x, Y2 = axisPos + dir * g.TickLength, Stroke = g.TickColor, StrokeWidth = g.LineWidth }); if (tk.Display) scene.Background.Add(new BitChartSvgText { - X = x, Y = plot.Bottom + g.TickLength + tk.Padding + tk.Font.Size * 0.5, + X = x + TickLabelOffset(tk), Y = axisPos + dir * (g.TickLength + tk.Padding + tk.Font.Size * 0.5), Text = tick.Label, Fill = tk.Color, FontFamily = tk.Font.Family, FontSize = tk.Font.Size, FontWeight = tk.Font.Weight, - Anchor = "middle", Baseline = "central" + Anchor = TickAnchor(tk), Baseline = "central" }); } } @@ -107,7 +140,7 @@ private void DrawValueAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS if (IsVertical) scene.Background.Add(new BitChartSvgText { - X = isRight ? axisPos + ReserveValueAxis(axis) - o.Title.Font.Size : axisPos - ReserveValueAxis(axis) + o.Title.Font.Size, + X = isRight ? axisPos + ReserveAxisWidth(axis) - o.Title.Font.Size : axisPos - ReserveAxisWidth(axis) + o.Title.Font.Size, Y = plot.CenterY, Text = o.Title.Text, Fill = o.Title.Color, FontFamily = o.Title.Font.Family, FontSize = o.Title.Font.Size, FontWeight = o.Title.Font.Weight, Anchor = "middle", Baseline = "central", Rotation = isRight ? 90 : -90 @@ -115,7 +148,11 @@ private void DrawValueAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS else scene.Background.Add(new BitChartSvgText { - X = plot.CenterX, Y = plot.Bottom + ReserveValueAxis(axis) - o.Title.Font.Size * 0.3, + // A value axis under a horizontal-bar chart reserves height, not width - and along + // the far (top) edge it reserves that height upwards, the same direction its ticks + // are drawn in. + X = plot.CenterX, + Y = axisPos + (isRight ? -1 : 1) * (ReserveAxisHeight(axis) - o.Title.Font.Size * 0.3), Text = o.Title.Text, Fill = o.Title.Color, FontFamily = o.Title.Font.Family, FontSize = o.Title.Font.Size, FontWeight = o.Title.Font.Weight, Anchor = "middle", Baseline = "central" @@ -129,14 +166,14 @@ private void DrawValueAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS if (IsVertical) scene.Background.Add(new BitChartSvgLine { X1 = axisPos, Y1 = plot.Top, X2 = axisPos, Y2 = plot.Bottom, Stroke = b.Color, StrokeWidth = b.Width, Dash = BitChartSvg.Dash(b.Dash) }); else - scene.Background.Add(new BitChartSvgLine { X1 = plot.Left, Y1 = plot.Bottom, X2 = plot.Right, Y2 = plot.Bottom, Stroke = b.Color, StrokeWidth = b.Width, Dash = BitChartSvg.Dash(b.Dash) }); + scene.Background.Add(new BitChartSvgLine { X1 = plot.Left, Y1 = axisPos, X2 = plot.Right, Y2 = axisPos, Stroke = b.Color, StrokeWidth = b.Width, Dash = BitChartSvg.Dash(b.Dash) }); } } - private void DrawIndexAxis(BitChartScene scene, BitChartArea plot, BitChartAxisScale axis) + private void DrawIndexAxis(BitChartScene scene, BitChartArea plot, BitChartAxisScale axis, double baseline) { var o = axis.Options; - if (!o.Display) return; + if (!ScaleVisible(o)) return; var g = o.Grid; var tk = o.Ticks; bool centered = HasBars(); @@ -158,7 +195,7 @@ private void DrawIndexAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS if (g.DrawTicks) scene.Background.Add(new BitChartSvgLine { - X1 = px, Y1 = plot.Bottom, X2 = px, Y2 = plot.Bottom + g.TickLength, + X1 = px, Y1 = baseline, X2 = px, Y2 = baseline + g.TickLength, Stroke = g.TickColor, StrokeWidth = g.LineWidth }); if (tk.Display) @@ -166,10 +203,10 @@ private void DrawIndexAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS double rot = axis.LabelRotation; scene.Background.Add(new BitChartSvgText { - X = px, Y = plot.Bottom + g.TickLength + tk.Padding + (Math.Abs(rot) > 1e-3 ? tk.Font.Size * 0.35 : tk.Font.Size * 0.7), + X = px + TickLabelOffset(tk), Y = baseline + g.TickLength + tk.Padding + (Math.Abs(rot) > 1e-3 ? tk.Font.Size * 0.35 : tk.Font.Size * 0.7), Text = tick.Label, Fill = tk.Color, FontFamily = tk.Font.Family, FontSize = tk.Font.Size, FontWeight = tk.Font.Weight, - Anchor = Math.Abs(rot) > 1e-3 ? "end" : "middle", Baseline = "auto", Rotation = rot + Anchor = Math.Abs(rot) > 1e-3 ? "end" : TickAnchor(tk), Baseline = "auto", Rotation = rot }); } } @@ -184,15 +221,16 @@ private void DrawIndexAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS if (g.DrawTicks) scene.Background.Add(new BitChartSvgLine { - X1 = plot.Left, Y1 = px, X2 = plot.Left - g.TickLength, Y2 = px, + X1 = baseline, Y1 = px, X2 = baseline - g.TickLength, Y2 = px, Stroke = g.TickColor, StrokeWidth = g.LineWidth }); if (tk.Display) scene.Background.Add(new BitChartSvgText { - X = plot.Left - g.TickLength - tk.Padding, Y = px, Text = tick.Label, Fill = tk.Color, + X = tk.Mirror ? baseline + g.TickLength + tk.Padding : baseline - g.TickLength - tk.Padding, + Y = px + TickLabelOffset(tk), Text = tick.Label, Fill = tk.Color, FontFamily = tk.Font.Family, FontSize = tk.Font.Size, FontWeight = tk.Font.Weight, - Anchor = "end", Baseline = "central" + Anchor = tk.Mirror ? "start" : "end", Baseline = "central" }); } } @@ -222,19 +260,30 @@ private void DrawIndexAxis(BitChartScene scene, BitChartArea plot, BitChartAxisS { var b = o.Border; if (IsVertical) - scene.Background.Add(new BitChartSvgLine { X1 = plot.Left, Y1 = plot.Bottom, X2 = plot.Right, Y2 = plot.Bottom, Stroke = b.Color, StrokeWidth = b.Width, Dash = BitChartSvg.Dash(b.Dash) }); + scene.Background.Add(new BitChartSvgLine { X1 = plot.Left, Y1 = baseline, X2 = plot.Right, Y2 = baseline, Stroke = b.Color, StrokeWidth = b.Width, Dash = BitChartSvg.Dash(b.Dash) }); else - scene.Background.Add(new BitChartSvgLine { X1 = plot.Left, Y1 = plot.Top, X2 = plot.Left, Y2 = plot.Bottom, Stroke = b.Color, StrokeWidth = b.Width, Dash = BitChartSvg.Dash(b.Dash) }); + scene.Background.Add(new BitChartSvgLine { X1 = baseline, Y1 = plot.Top, X2 = baseline, Y2 = plot.Bottom, Stroke = b.Color, StrokeWidth = b.Width, Dash = BitChartSvg.Dash(b.Dash) }); } } private bool HasBars() => _data.Datasets.Where((d, i) => !IsHidden(i, d)).Any(d => EffectiveType(d) == BitChartType.Bar); + /// Text anchor for a tick label honoring . + private static string TickAnchor(BitChartTickOptions tk) => tk.Align switch + { + BitChartAlign.Start => "start", + BitChartAlign.End => "end", + _ => "middle" + }; + + /// Extra pixel shift applied to a tick label along the axis. + private static double TickLabelOffset(BitChartTickOptions tk) => tk.LabelOffset; + /// Draws a secondary x-axis (ticks/labels/border/title) at a baseline outside the plot. private void DrawSecondaryXAxis(BitChartScene scene, BitChartArea plot, BitChartAxisScale axis, double baselineY, bool atBottom) { var o = axis.Options; - if (!o.Display) return; + if (!ScaleVisible(o)) return; var g = o.Grid; var tk = o.Ticks; int dir = atBottom ? 1 : -1; @@ -254,7 +303,7 @@ private void DrawSecondaryXAxis(BitChartScene scene, BitChartArea plot, BitChart X = px, Y = baselineY + dir * (g.TickLength + tk.Padding + tk.Font.Size * (atBottom ? 0.7 : 0.1)), Text = tick.Label, Fill = tk.Color, FontFamily = tk.Font.Family, FontSize = tk.Font.Size, FontWeight = tk.Font.Weight, - Anchor = "middle", Baseline = atBottom ? "auto" : "auto" + Anchor = "middle", Baseline = "auto" }); } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Circular.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Circular.cs index c8b10715de..fcd7d69ee0 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Circular.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Circular.cs @@ -1,5 +1,3 @@ -using System.Globalization; - namespace Bit.BlazorUI; public sealed partial class BitChartRenderer @@ -18,36 +16,53 @@ private void RenderCircular(BitChartScene scene) return; } - var datasets = _data.Datasets.Where((d, i) => !d.Hidden && !_state.IsDatasetHidden(i)).ToList(); + var datasets = _data.Datasets + .Select((d, i) => (ds: d, index: i)) + .Where(t => !t.ds.Hidden && !_state.IsDatasetHidden(t.index)) + .ToList(); if (datasets.Count == 0) return; double rotation = _options.RotationDegrees * Math.PI / 180; double circumference = _options.CircumferenceDegrees * Math.PI / 180; - double cutout = _config.Type == BitChartType.Doughnut ? _options.CutoutPercentage / 100.0 : 0; + // Clamped: a cutout at or past 100% would put the inner radius outside the outer one and + // invert every arc. + double cutout = _config.Type == BitChartType.Doughnut + ? Math.Clamp(_options.CutoutPercentage / 100.0, 0, 0.95) + : 0; double ringOuter = maxR; double ringInner = maxR * cutout; - double ringThickness = (ringOuter - ringInner) / datasets.Count; + + // Ring thickness is shared out by weight, so one dataset can be given a thicker band than the + // others. With every weight left at its default of 1 this is an even split, exactly as before. + double ringSpan = ringOuter - ringInner; + double totalWeight = datasets.Sum(t => Math.Max(0, t.ds.Weight)); + if (totalWeight <= 0) totalWeight = datasets.Count; var ctx = new BitChartPluginContext { - Scene = scene, Config = _config, IsCartesian = false, + Scene = scene, Config = _config, IsCartesian = false, HiddenDatasets = _state.HiddenDatasets, CenterX = cx, CenterY = cy, InnerRadius = ringInner, OuterRadius = ringOuter }; foreach (var plugin in _options.Plugins.Custom) plugin.BeforeDatasetsDraw(ctx); + double ringCursor = ringOuter; for (int ri = 0; ri < datasets.Count; ri++) { - var ds = datasets[ri]; - int dsIndex = _data.Datasets.IndexOf(ds); - double outer = ringOuter - ringThickness * ri; - double inner = outer - ringThickness; + var (ds, dsIndex) = datasets[ri]; + double outer = ringCursor; + double inner = outer - ringSpan * (Math.Max(0, ds.Weight) / totalWeight); + ringCursor = inner; double total = 0; for (int i = 0; i < ds.Data.Count; i++) if (!_state.IsIndexHidden(i) && ds.Data[i] is { } v) total += Math.Abs(v); if (total <= 0) continue; + double arcBorderWidth = ResolveBorderWidth(ds, _config.Type, dsIndex); + // The angular half-gap that realizes the requested pixel spacing at the outer edge. + double halfGap = ds.SpacingArc > 0 && outer > 0 ? ds.SpacingArc / 2 / outer : 0; + double angle = rotation; for (int i = 0; i < ds.Data.Count; i++) { @@ -57,44 +72,76 @@ private void RenderCircular(BitChartScene scene) double a1 = angle + slice; angle = a1; + // Apply the inter-arc gap without letting it swallow a very thin slice. + double gap = Math.Min(halfGap, Math.Max(0, (a1 - a0) / 4)); + double d0 = a0 + gap, d1 = a1 - gap; + string bg = ResolveBackground(ds, dsIndex, i, true); - bool active = _state.Active == (dsIndex, i); - double offset = ds.Offset + (active ? 6 : 0); + string arcBorder = ResolveBorder(ds, dsIndex, i, true, v, fallbackToBackground: false); + string borderColor = HasExplicitBorder(ds) ? arcBorder : _options.Elements.ArcBorderColor; double mid = (a0 + a1) / 2; - double ox = active || ds.Offset > 0 ? Math.Cos(mid) * offset : 0; - double oy = active || ds.Offset > 0 ? Math.Sin(mid) * offset : 0; + double ox = ds.Offset > 0 ? Math.Cos(mid) * ds.Offset : 0; + double oy = ds.Offset > 0 ? Math.Sin(mid) * ds.Offset : 0; var path = new BitChartSvgPath { - D = ArcPath(cx + ox, cy + oy, inner, outer, a0, a1), - Fill = active ? BitChartColorUtil.Adjust(bg, 0.08) : bg, - Stroke = _options.Elements.ArcBorderColor, - StrokeWidth = _options.Elements.ArcBorderWidth + D = ArcPath(cx + ox, cy + oy, inner, outer, d0, d1, ds.BorderRadius), + Fill = bg, + Stroke = borderColor, + StrokeWidth = arcBorderWidth + }; + + // Hover: the arc is pushed further out and repainted with the hover colors. Precomputed + // so hovering an arc never costs a full re-layout. + double hoverOffset = ds.Offset + ds.HoverOffset; + string hoverBg = ds.HoverBackgroundColor + ?? (ds.BackgroundColorFn is not null ? ResolveBackground(ds, dsIndex, i, true, v, active: true) : BitChartColorUtil.Adjust(bg, 0.08)); + var hoverPath = new BitChartSvgPath + { + D = ArcPath(cx + Math.Cos(mid) * hoverOffset, cy + Math.Sin(mid) * hoverOffset, inner, outer, d0, d1, ds.BorderRadius), + Fill = hoverBg, + Stroke = ds.HoverBorderColor ?? borderColor, + StrokeWidth = ds.HoverBorderWidth ?? arcBorderWidth }; - double pct = total > 0 ? Math.Abs(v) / total * 100 : 0; + double pct = Math.Abs(v) / total * 100; + string label = i < _data.Labels.Count ? _data.Labels[i] : ds.Label ?? ""; + string text = _options.Plugins.Tooltip.Callbacks.Label is not null || _options.Plugins.Tooltip.LabelFormatter is not null + ? BuildItemText(ds, dsIndex, i, v, bg) + : $"{FormatNumber(v, "0.##")} ({FormatNumber(pct, "0.#")}%)"; + scene.Elements.Add(new BitChartDataElement { Shape = path, + HoverShape = hoverPath, DatasetIndex = dsIndex, DataIndex = i, - CenterX = cx + Math.Cos(mid) * (inner + outer) / 2, - CenterY = cy + Math.Sin(mid) * (inner + outer) / 2, + // Offset like the arc itself, so an exploded slice keeps its hover shape and + // its tooltip over the slice rather than over where it would sit unexploded. + CenterX = cx + ox + Math.Cos(mid) * (inner + outer) / 2, + CenterY = cy + oy + Math.Sin(mid) * (inner + outer) / 2, Value = v, - SeriesLabel = i < _data.Labels.Count ? _data.Labels[i] : ds.Label, + SeriesLabel = label, Tooltip = new BitChartTooltipInfo { Title = i < _data.Labels.Count ? _data.Labels[i] : null, - AnchorX = cx + Math.Cos(mid) * outer, - AnchorY = cy + Math.Sin(mid) * outer, - Items = { new BitChartTooltipItem { Color = bg, Text = $"{v.ToString("0.##", CultureInfo.InvariantCulture)} ({pct.ToString("0.#", CultureInfo.InvariantCulture)}%)" } } + AnchorX = cx + ox + Math.Cos(mid) * outer, + AnchorY = cy + oy + Math.Sin(mid) * outer, + Items = { new BitChartTooltipItem { Color = bg, Text = text } } } }); if (_options.Plugins.DataLabels.Display && slice > 0.15) { - double lr = (inner + outer) / 2; - AddDataLabel(scene, v, cx + Math.Cos(mid) * lr, cy + Math.Sin(mid) * lr + 4, dsIndex, i); + var dl = _options.Plugins.DataLabels; + double lr = dl.Anchor switch + { + BitChartAlign.Start => inner + (inner > 0 ? 0 : 0.35 * outer), + BitChartAlign.End => outer, + _ => (inner + outer) / 2 + }; + lr += AlignShift(dl, 1); + AddDataLabel(scene, v, cx + ox + Math.Cos(mid) * lr, cy + oy + Math.Sin(mid) * lr, dsIndex, i); } } } @@ -104,9 +151,13 @@ private void RenderCircular(BitChartScene scene) private void RenderPolarArea(BitChartScene scene, double cx, double cy, double maxR) { - var ds = _data.Datasets.FirstOrDefault(); - if (ds is null) return; - int dsIndex = 0; + // The polar scale is shared by the whole chart, so it draws the first *visible* dataset - + // hiding it from the legend has to empty the chart rather than leave it drawn. + int dsIndex = -1; + for (int k = 0; k < _data.Datasets.Count; k++) + if (!IsHidden(k, _data.Datasets[k])) { dsIndex = k; break; } + if (dsIndex < 0) return; + var ds = _data.Datasets[dsIndex]; int n = ds.Data.Count; if (n == 0) return; @@ -115,58 +166,67 @@ private void RenderPolarArea(BitChartScene scene, double cx, double cy, double m if (!_state.IsIndexHidden(i) && ds.Data[i] is { } v) maxVal = Math.Max(maxVal, v); if (maxVal <= 0) maxVal = 1; - var rOpts0 = _options.Scales["r"]; - // Reserve room for perimeter point labels. - if (rOpts0.PointLabels.Display && _data.Labels.Count > 0) - maxR -= rOpts0.PointLabels.Font.Size + rOpts0.PointLabels.Padding + 6; + var rOpts = Scale(RadialScaleId); + double sliceAngle = 2 * Math.PI / n; + double rotation = (_options.RotationDegrees + rOpts.StartAngle) * Math.PI / 180; + + // Reserve room for perimeter point labels, measured the same way the radar chart does. + if (PointLabelsVisible(rOpts) && _data.Labels.Count > 0) + maxR -= PointLabelReserve(rOpts.PointLabels, _data.Labels, n, rotation + sliceAngle / 2, sliceAngle); if (maxR <= 0) return; - var rScale = new BitChartAxisScale(_options.Scales["r"], horizontal: false); + var rScale = new BitChartAxisScale(rOpts, horizontal: false) { Culture = Culture }; rScale.SetDataRange(0, maxVal); rScale.SetPixelRange(0, maxR); + var pctx = new BitChartPluginContext + { + Scene = scene, Config = _config, IsCartesian = false, HiddenDatasets = _state.HiddenDatasets, + CenterX = cx, CenterY = cy, InnerRadius = 0, OuterRadius = maxR + }; + foreach (var plugin in _options.Plugins.Custom) plugin.BeforeDatasetsDraw(pctx); + // Radial grid circles. - var rOpts = _options.Scales["r"]; - if (rOpts.Display && rOpts.Grid.Display) + if (ScaleVisible(rOpts) && rOpts.Grid.Display) { foreach (var t in rScale.Ticks) { double rr = t.Pixel; if (rr <= 0) continue; scene.Background.Add(new BitChartSvgCircle { Cx = cx, Cy = cy, R = rr, Fill = "none", Stroke = rOpts.Grid.Color, StrokeWidth = rOpts.Grid.LineWidth }); - if (rOpts.Ticks.Display) - { - if (rOpts.ShowLabelBackdrop) - { - double w = BitChartTextMeasure.Width(t.Label, rOpts.Ticks.Font.Size) + 4; - scene.Background.Add(new BitChartSvgRect { X = cx + 2, Y = cy - rr - rOpts.Ticks.Font.Size * 0.55, Width = w, Height = rOpts.Ticks.Font.Size + 2, Fill = rOpts.BackdropColor }); - } - scene.Background.Add(new BitChartSvgText { X = cx + 4, Y = cy - rr, Text = t.Label, Fill = rOpts.Ticks.Color, FontSize = rOpts.Ticks.Font.Size, FontFamily = rOpts.Ticks.Font.Family, Anchor = "start", Baseline = "central" }); - } + if (rOpts.Ticks.Display) AddRadialTickLabel(scene, rOpts, cx, cy, rr, t.Label); } } - double rotation = (_options.RotationDegrees + rOpts.StartAngle) * Math.PI / 180; - double sliceAngle = 2 * Math.PI / n; + double arcBorderWidth = ResolveBorderWidth(ds, BitChartType.PolarArea, dsIndex); double angle = rotation; for (int i = 0; i < n; i++) { if (_state.IsIndexHidden(i) || ds.Data[i] is not { } v) { angle += sliceAngle; continue; } double a0 = angle, a1 = angle + sliceAngle; angle = a1; - double r = rScale.PixelFor(v); + double halfGap = ds.SpacingArc > 0 && maxR > 0 ? Math.Min(ds.SpacingArc / 2 / maxR, sliceAngle / 4) : 0; + // A value below the scale minimum maps to a negative radius, which would draw the wedge + // inside out through the center; a polar wedge simply has no length there. + double r = Math.Clamp(rScale.PixelFor(v), 0, maxR); string bg = ResolveBackground(ds, dsIndex, i, true); - bool active = _state.Active == (dsIndex, i); var path = new BitChartSvgPath { - D = ArcPath(cx, cy, 0, r, a0, a1), - Fill = BitChartColorUtil.WithAlpha(active ? BitChartColorUtil.Adjust(bg, -0.1) : bg, 0.7), - Stroke = bg, StrokeWidth = _options.Elements.ArcBorderWidth + D = ArcPath(cx, cy, 0, r, a0 + halfGap, a1 - halfGap, ds.BorderRadius), + Fill = BitChartColorUtil.WithAlpha(bg, 0.7), + Stroke = bg, StrokeWidth = arcBorderWidth + }; + var hoverPath = new BitChartSvgPath + { + D = ArcPath(cx, cy, 0, r, a0 + halfGap, a1 - halfGap, ds.BorderRadius), + Fill = BitChartColorUtil.WithAlpha(ds.HoverBackgroundColor ?? BitChartColorUtil.Adjust(bg, -0.1), 0.85), + Stroke = ds.HoverBorderColor ?? bg, StrokeWidth = ds.HoverBorderWidth ?? arcBorderWidth }; double mid = (a0 + a1) / 2; scene.Elements.Add(new BitChartDataElement { Shape = path, + HoverShape = hoverPath, DatasetIndex = dsIndex, DataIndex = i, CenterX = cx + Math.Cos(mid) * r / 2, @@ -178,13 +238,28 @@ private void RenderPolarArea(BitChartScene scene, double cx, double cy, double m Title = i < _data.Labels.Count ? _data.Labels[i] : null, AnchorX = cx + Math.Cos(mid) * r, AnchorY = cy + Math.Sin(mid) * r, - Items = { new BitChartTooltipItem { Color = bg, Text = v.ToString("0.##", CultureInfo.InvariantCulture) } } + Items = { new BitChartTooltipItem { Color = bg, Text = BuildItemText(ds, dsIndex, i, v, bg) } } } }); + + if (_options.Plugins.DataLabels.Display) + { + // Placed the way a doughnut places its labels, with the wedge running from the center + // out to its own radius. + var dl = _options.Plugins.DataLabels; + double lr = dl.Anchor switch + { + BitChartAlign.Start => 0.35 * r, + BitChartAlign.End => r, + _ => r / 2 + }; + lr += AlignShift(dl, 1); + AddDataLabel(scene, v, cx + Math.Cos(mid) * lr, cy + Math.Sin(mid) * lr, dsIndex, i); + } } // Perimeter category (point) labels. - if (rOpts.PointLabels.Display && _data.Labels.Count > 0) + if (PointLabelsVisible(rOpts) && _data.Labels.Count > 0) { var pl = rOpts.PointLabels; double a = rotation; @@ -206,6 +281,121 @@ private void RenderPolarArea(BitChartScene scene, double cx, double cy, double m }); } } + + foreach (var plugin in _options.Plugins.Custom) plugin.AfterDatasetsDraw(pctx); + } + + /// + /// How much room the perimeter labels of a radial chart need. Each label is measured and projected + /// onto its own angle - a label at the side sticks out by its full width, one at the top or bottom + /// only by half - so the plot shrinks by what the longest label actually needs and no more. + /// + private static double PointLabelReserve(BitChartPointLabelOptions pl, List labels, int count, + double startAngle, double angleStep) + { + double needed = pl.Font.LineHeightPx; + for (int i = 0; i < count && i < labels.Count; i++) + { + double a = startAngle + angleStep * i; + double w = BitChartTextMeasure.Width(pl.Callback?.Invoke(labels[i], i) ?? labels[i], pl.Font.Size, pl.Font.Weight); + double cos = Math.Abs(Math.Cos(a)); + // Near-vertical labels are centered on the spoke, so only half of them sticks out. + double horizontal = cos * (cos < 0.3 ? w / 2 : w); + double vertical = Math.Abs(Math.Sin(a)) * pl.Font.LineHeightPx; + needed = Math.Max(needed, horizontal + vertical); + } + return needed + pl.Padding + 6; + } + + /// Draws one radial tick label, optionally over a backdrop so it stays readable on the grid. + private static void AddRadialTickLabel(BitChartScene scene, BitChartScaleOptions rOpts, double cx, double cy, double rr, string label) + { + if (rOpts.ShowLabelBackdrop) + { + double w = BitChartTextMeasure.Width(label, rOpts.Ticks.Font.Size) + 4; + scene.Background.Add(new BitChartSvgRect + { + X = cx + 2, Y = cy - rr - rOpts.Ticks.Font.Size * 0.55, + Width = w, Height = rOpts.Ticks.Font.Size + 2, Fill = rOpts.BackdropColor + }); + } + scene.Background.Add(new BitChartSvgText + { + X = cx + 4, Y = cy - rr, Text = label, Fill = rOpts.Ticks.Color, + FontSize = rOpts.Ticks.Font.Size, FontFamily = rOpts.Ticks.Font.Family, Anchor = "start", Baseline = "central" + }); + } + + /// + /// Builds an arc path, rounding its corners when the dataset asks for it. A zero radius - or an arc + /// that has come round to a full circle, which has no corners to round - falls through to the plain + /// path, so nothing changes for the charts that never set one. + /// + private static string ArcPath(double cx, double cy, double inner, double outer, double a0, double a1, double cornerRadius) + => cornerRadius > 0 && a1 - a0 < 2 * Math.PI - 1e-3 + ? RoundedArcPath(cx, cy, inner, outer, a0, a1, cornerRadius) + : ArcPath(cx, cy, inner, outer, a0, a1); + + /// + /// Builds an arc/ring path whose corners are rounded, mirroring Chart.js's arc borderRadius. + /// Each corner is cut back along both edges that meet there and reconnected with a quadratic curve + /// through the true corner point, which reads as a fillet at any radius and cannot self-intersect: + /// the radius is clamped to half the ring's thickness and half its arc length first. A pie arc has + /// no inner edge, so only the two outer corners are rounded - its point sits at the center. + /// + private static string RoundedArcPath(double cx, double cy, double inner, double outer, double a0, double a1, double radius) + { + double span = a1 - a0; + double thickness = outer - Math.Max(0, inner); + if (span <= 0 || thickness <= 0) return ArcPath(cx, cy, inner, outer, a0, a1); + + // The outer edge is the longest, so it decides how much of a corner there is room for. + double r = Math.Min(radius, thickness / 2); + r = Math.Min(r, span * outer / 2); + if (r <= 0.01) return ArcPath(cx, cy, inner, outer, a0, a1); + + (double X, double Y) P(double rad, double ang) => (cx + rad * Math.Cos(ang), cy + rad * Math.Sin(ang)); + static string M((double X, double Y) p) => $"M {BitChartSvg.N(p.X)} {BitChartSvg.N(p.Y)} "; + static string L((double X, double Y) p) => $"L {BitChartSvg.N(p.X)} {BitChartSvg.N(p.Y)} "; + static string Q((double X, double Y) c, (double X, double Y) p) + => $"Q {BitChartSvg.N(c.X)} {BitChartSvg.N(c.Y)}, {BitChartSvg.N(p.X)} {BitChartSvg.N(p.Y)} "; + string A(double rad, (double X, double Y) p, int sweep, double from, double to) + => $"A {BitChartSvg.N(rad)} {BitChartSvg.N(rad)} 0 {(Math.Abs(to - from) > Math.PI ? 1 : 0)} {sweep} {BitChartSvg.N(p.X)} {BitChartSvg.N(p.Y)} "; + + // Angular size of the corner on each edge: the same arc length r, so a tighter radius covers + // more angle on the inner edge than on the outer one. + double outerCut = r / outer; + double oa0 = a0 + outerCut, oa1 = a1 - outerCut; + if (oa1 < oa0) { double mid = (a0 + a1) / 2; oa0 = oa1 = mid; } + + var sb = new System.Text.StringBuilder(); + if (inner <= 0.01) + { + // Pie wedge: center → rounded outer start → outer arc → rounded outer end → center. + sb.Append(M((cx, cy))); + sb.Append(L(P(outer - r, a0))); + sb.Append(Q(P(outer, a0), P(outer, oa0))); + sb.Append(A(outer, P(outer, oa1), 1, oa0, oa1)); + sb.Append(Q(P(outer, a1), P(outer - r, a1))); + sb.Append('Z'); + return sb.ToString(); + } + + double innerCut = Math.Min(r / inner, span / 2); + double ia0 = a0 + innerCut, ia1 = a1 - innerCut; + if (ia1 < ia0) { double mid = (a0 + a1) / 2; ia0 = ia1 = mid; } + + sb.Append(M(P(inner + r, a0))); + sb.Append(L(P(outer - r, a0))); + sb.Append(Q(P(outer, a0), P(outer, oa0))); + sb.Append(A(outer, P(outer, oa1), 1, oa0, oa1)); + sb.Append(Q(P(outer, a1), P(outer - r, a1))); + sb.Append(L(P(inner + r, a1))); + sb.Append(Q(P(inner, a1), P(inner, ia1))); + sb.Append(A(inner, P(inner, ia0), 0, ia1, ia0)); + sb.Append(Q(P(inner, a0), P(inner + r, a0))); + sb.Append('Z'); + return sb.ToString(); } /// Builds an SVG arc/ring path. Handles full circles. diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Radar.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Radar.cs index 65ca0864a8..3c07711408 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Radar.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Radar.cs @@ -9,11 +9,15 @@ private void RenderRadar(BitChartScene scene) int n = _data.Labels.Count; if (n == 0) return; - var rOpts = _options.Scales["r"]; + var rOpts = Scale(RadialScaleId); - // Reserve room for the point labels around the perimeter. - double labelPad = rOpts.PointLabels.Display - ? rOpts.PointLabels.Font.Size + rOpts.PointLabels.Padding + 14 + double angleStepForLabels = 2 * Math.PI / n; + double startForLabels = -Math.PI / 2 + rOpts.StartAngle * Math.PI / 180; + + // Reserve room for the point labels around the perimeter. The labels are measured rather than + // assumed: a long category name reaching out sideways would otherwise be cut off by the chart box. + double labelPad = PointLabelsVisible(rOpts) + ? PointLabelReserve(rOpts.PointLabels, _data.Labels, n, startForLabels, angleStepForLabels) : 8; double cx = area.CenterX; double cy = area.CenterY; @@ -29,15 +33,22 @@ private void RenderRadar(BitChartScene scene) } if (double.IsInfinity(max)) max = 1; - var rScale = new BitChartAxisScale(rOpts, horizontal: false); + var rScale = new BitChartAxisScale(rOpts, horizontal: false) { Culture = Culture }; rScale.SetDataRange(rOpts.BeginAtZero ? 0 : min, max); rScale.SetPixelRange(0, maxR); - double angleStep = 2 * Math.PI / n; - double start = -Math.PI / 2 + rOpts.StartAngle * Math.PI / 180; + double angleStep = angleStepForLabels; + double start = startForLabels; + + var pctx = new BitChartPluginContext + { + Scene = scene, Config = _config, IsCartesian = false, HiddenDatasets = _state.HiddenDatasets, + CenterX = cx, CenterY = cy, InnerRadius = 0, OuterRadius = maxR + }; + foreach (var plugin in _options.Plugins.Custom) plugin.BeforeDatasetsDraw(pctx); // Grid rings (polygons by default, circles when grid.circular). - if (rOpts.Display && rOpts.Grid.Display) + if (ScaleVisible(rOpts) && rOpts.Grid.Display) { foreach (var t in rScale.Ticks) { @@ -66,7 +77,7 @@ private void RenderRadar(BitChartScene scene) double a = start + angleStep * i; double ex = cx + Math.Cos(a) * maxR; double ey = cy + Math.Sin(a) * maxR; - if (rOpts.Display && rOpts.AngleLines) + if (ScaleVisible(rOpts) && rOpts.AngleLines) scene.Background.Add(new BitChartSvgLine { X1 = cx, Y1 = cy, X2 = ex, Y2 = ey, @@ -74,7 +85,7 @@ private void RenderRadar(BitChartScene scene) Dash = BitChartSvg.Dash(rOpts.AngleLineDash) }); - if (rOpts.PointLabels.Display) + if (PointLabelsVisible(rOpts)) { var pl = rOpts.PointLabels; double lx = cx + Math.Cos(a) * (maxR + pl.Padding + 4); @@ -91,18 +102,13 @@ private void RenderRadar(BitChartScene scene) } // Radial tick labels (with optional backdrop). - if (rOpts.Display && rOpts.Ticks.Display) + if (ScaleVisible(rOpts) && rOpts.Ticks.Display) { foreach (var t in rScale.Ticks) { double rr = t.Pixel; if (rr <= 0.01) continue; - if (rOpts.ShowLabelBackdrop) - { - double w = BitChartTextMeasure.Width(t.Label, rOpts.Ticks.Font.Size) + 4; - scene.Background.Add(new BitChartSvgRect { X = cx + 2, Y = cy - rr - rOpts.Ticks.Font.Size * 0.55, Width = w, Height = rOpts.Ticks.Font.Size + 2, Fill = rOpts.BackdropColor }); - } - scene.Background.Add(new BitChartSvgText { X = cx + 4, Y = cy - rr, Text = t.Label, Fill = rOpts.Ticks.Color, FontSize = rOpts.Ticks.Font.Size, FontFamily = rOpts.Ticks.Font.Family, Anchor = "start", Baseline = "central" }); + AddRadialTickLabel(scene, rOpts, cx, cy, rr, t.Label); } } @@ -112,7 +118,7 @@ private void RenderRadar(BitChartScene scene) var ds = _data.Datasets[d]; if (IsHidden(d, ds)) continue; string border = ResolveBorder(ds, d, 0, false); - string fill = ds.FillColor ?? BitChartColorUtil.WithAlpha(border, 0.2); + string fill = ResolveFill(scene, ds, border); var verts = new List<(double x, double y, int di)>(); for (int i = 0; i < n && i < ds.Data.Count; i++) @@ -131,11 +137,14 @@ private void RenderRadar(BitChartScene scene) Points = verts.Select(p => (p.x, p.y)).ToList(), Fill = ds.Fill != BitChartFillMode.None ? fill : "none", Stroke = border, - StrokeWidth = ds.BorderWidth <= 1 ? 2 : ds.BorderWidth + StrokeWidth = ResolveBorderWidth(ds, BitChartType.Radar, d) }); - foreach (var p in verts) - AddPoint(scene, ds, d, p.di, p.x, p.y, ds.Data[p.di] ?? 0, Math.Max(3, ds.PointRadius), border); + if (ds.PointStyle != BitChartPointStyle.None) + foreach (var p in verts) + AddPoint(scene, ds, d, p.di, p.x, p.y, ds.Data[p.di] ?? 0, Math.Max(3, ResolvePointRadius(ds)), border); } + + foreach (var plugin in _options.Plugins.Custom) plugin.AfterDatasetsDraw(pctx); } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Series.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Series.cs index 813f16f910..84abb87539 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Series.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.Series.cs @@ -9,22 +9,43 @@ private void DrawBars(BitChartScene scene, BitChartArea plot, BitChartAxisScale { if (barItems.Count == 0) return; - // Build slots: stacked datasets share a slot, others get their own. + // Build slots: stacked datasets share a slot, others get their own. A dataset with + // Grouped = false opts out of the layout entirely and spans the whole category band. var slotKeys = new List(); var dsSlot = new Dictionary(); foreach (var (ds, i) in barItems) { + if (!ds.Grouped) { dsSlot[i] = -1; continue; } bool stacked = valueScales[ds.YAxisID].Options.Stacked; string key = stacked ? $"stack:{ds.Stack ?? "default"}:{ds.YAxisID}" : $"ds:{i}"; - if (!slotKeys.Contains(key)) slotKeys.Add(key); - dsSlot[i] = slotKeys.IndexOf(key); + int at = slotKeys.IndexOf(key); + if (at < 0) { slotKeys.Add(key); at = slotKeys.Count - 1; } + dsSlot[i] = at; } int slotCount = Math.Max(1, slotKeys.Count); double band = indexScale.BandWidth(); var first = barItems[0].d; double categorySize = band * first.CategoryPercentage; - double slotSize = categorySize / slotCount; + + // Per-index slot layout. With SkipNull the slots whose datasets have no value at an index are + // dropped, so the remaining bars widen to fill the category instead of leaving a hole. + bool skipNull = barItems.Any(t => t.d.SkipNull); + var allSlots = Enumerable.Range(0, slotKeys.Count).ToList(); + var perIndexSlots = new Dictionary>(); + List SlotsAt(int di) + { + if (!skipNull) return allSlots; + if (perIndexSlots.TryGetValue(di, out var cached)) return cached; + var live = new List(); + for (int k = 0; k < slotKeys.Count; k++) + { + bool any = barItems.Any(t => dsSlot[t.i] == k && HasValueAt(t.d, di)); + if (any) live.Add(k); + } + perIndexSlots[di] = live; + return live; + } var stackOffset = new Dictionary<(int slot, int di, int sign), double>(); @@ -40,18 +61,25 @@ private void DrawBars(BitChartScene scene, BitChartArea plot, BitChartAxisScale stack100Totals[(slot, di)] = stack100Totals.GetValueOrDefault((slot, di), 0) + Math.Abs(v); } + // The value-axis baseline every bar grows out of. Taken from the first bar dataset (they share + // the axis) so the group entry animation always scales out of the axis line - not out of + // whatever the last drawn bar happened to sit on. + var firstScale = valueScales[first.YAxisID]; + double axisBaseValue = first.Base ?? Math.Clamp(0, Math.Min(firstScale.Min, firstScale.Max), Math.Max(firstScale.Min, firstScale.Max)); + scene.BarBaseline = firstScale.PixelFor(axisBaseValue); + foreach (var (ds, i) in barItems) { var vScale = valueScales[ds.YAxisID]; bool stacked = vScale.Options.Stacked; bool stacked100 = stacked && vScale.Options.Stacked100; int slot = dsSlot[i]; - double barSize = slotSize * ds.BarPercentage; - if (ds.BarThickness is { } bt) barSize = bt; - if (ds.MaxBarThickness is { } mbt) barSize = Math.Min(barSize, mbt); + var barType = EffectiveType(ds); int count = ds.Count; string? patternFill = ds.BackgroundPattern is { } pat ? RegisterPattern(scene, pat) : null; + double borderWidth = ResolveBorderWidth(ds, BitChartType.Bar, i); + for (int di = 0; di < count; di++) { double baseVal, topVal, tooltipVal; @@ -81,139 +109,254 @@ private void DrawBars(BitChartScene scene, BitChartArea plot, BitChartAxisScale } else { - baseVal = Math.Clamp(0, Math.Min(vScale.Min, vScale.Max), Math.Max(vScale.Min, vScale.Max)); + baseVal = ds.Base ?? Math.Clamp(0, Math.Min(vScale.Min, vScale.Max), Math.Max(vScale.Min, vScale.Max)); topVal = value; } } + // Slot geometry for this index. + double slotSize, slotCenter; double centerAlong = indexIsCategory ? indexScale.PixelForIndex(di, true) : indexScale.PixelFor(di); - double slotCenter = centerAlong - categorySize / 2 + slot * slotSize + slotSize / 2; + if (slot < 0) + { + slotSize = categorySize; + slotCenter = centerAlong; + } + else + { + var live = SlotsAt(di); + int ordinal = live.IndexOf(slot); + int liveCount = Math.Max(1, live.Count); + if (ordinal < 0) { ordinal = slot; liveCount = slotCount; } + slotSize = categorySize / liveCount; + slotCenter = centerAlong - categorySize / 2 + ordinal * slotSize + slotSize / 2; + } + + double barSize = slotSize * ds.BarPercentage; + if (ds.BarThickness is { } bt) barSize = bt; + if (ds.MaxBarThickness is { } mbt) barSize = Math.Min(barSize, mbt); string bg = ResolveBackground(ds, i, di, false, tooltipVal); - string border = ResolveBorder(ds, i, di, false, tooltipVal); + string border = ResolveBorder(ds, i, di, false, tooltipVal, fallbackToBackground: true); if (patternFill is not null) bg = patternFill; - int signFinal = topVal >= baseVal ? 1 : -1; double inflate = ds.InflateAmount ?? 0; + double minLen = ds.MinBarLength ?? 1; BitChartSvgRect rect; - double cx, cy, originX, originY; + double cx, cy; + + // Which way the bar grows is a question about pixels, not about the sign of the value: a + // reversed axis puts a positive bar below its baseline. Everything downstream - the + // skipped edge, the rounded corners, the data label - follows this, not the raw sign. + int signFinal; if (IsVertical) { double yBase = vScale.PixelFor(baseVal); double yTop = vScale.PixelFor(topVal); + signFinal = yTop <= yBase ? 1 : -1; + // A minimum length still grows away from the baseline rather than straddling it. + double height = Math.Max(minLen, Math.Abs(yBase - yTop)); + double y = signFinal >= 0 ? yBase - height : yBase; rect = new BitChartSvgRect { X = slotCenter - barSize / 2 - inflate, - Y = Math.Min(yBase, yTop) - inflate, + Y = y - inflate, Width = barSize + inflate * 2, - Height = Math.Max(1, Math.Abs(yBase - yTop)) + inflate * 2, - Fill = bg, - Rx = ds.BorderRadius + Height = height + inflate * 2, + Fill = bg }; - cx = slotCenter; cy = yTop; - originX = slotCenter; originY = yBase; // grow from the baseline - scene.BarBaseline = yBase; + cx = slotCenter; cy = signFinal >= 0 ? rect.Y : rect.Y + rect.Height; } else { double xBase = vScale.PixelFor(baseVal); double xTop = vScale.PixelFor(topVal); + signFinal = xTop >= xBase ? 1 : -1; + double width = Math.Max(minLen, Math.Abs(xBase - xTop)); + double x = signFinal >= 0 ? xBase : xBase - width; rect = new BitChartSvgRect { - X = Math.Min(xBase, xTop) - inflate, + X = x - inflate, Y = slotCenter - barSize / 2 - inflate, - Width = Math.Max(1, Math.Abs(xBase - xTop)) + inflate * 2, + Width = width + inflate * 2, Height = barSize + inflate * 2, - Fill = bg, - Rx = ds.BorderRadius + Fill = bg }; - cx = xTop; cy = slotCenter; - originX = xBase; originY = slotCenter; // grow from the baseline - scene.BarBaseline = xBase; + cx = signFinal >= 0 ? rect.X + rect.Width : rect.X; cy = slotCenter; } - // Per-corner radius emits a rounded path instead of a plain rect. - BitChartSvgNode shapeNode = rect; - bool perCorner = ds.BorderRadiusCorners is { } c0 && - (c0.TopLeft > 0 || c0.TopRight > 0 || c0.BottomRight > 0 || c0.BottomLeft > 0); - - // Effective corner radii (explicit per-corner, else uniform BorderRadius) used so the - // border follows the same rounded outline as the fill. - BitChartBorderRadiusCorners? roundedCorners = null; - if (perCorner) roundedCorners = ds.BorderRadiusCorners!.Value; - else if (ds.BorderRadius > 0) roundedCorners = ds.BorderRadius; // implicit double -> all corners - var skip = ResolveSkip(isRange ? BitChartBorderSkipped.None : ds.BorderSkipped, IsVertical, signFinal); - if (perCorner) + // Effective corner radii. Chart.js only rounds the corners that are not adjacent to the + // skipped (baseline) edge, so a bar with a uniform BorderRadius rounds its tip and keeps + // a flat foot on the axis. BorderSkipped.None opts back into rounding all four corners. + BitChartBorderRadiusCorners? roundedCorners = ds.BorderRadiusCorners + ?? (ds.BorderRadius > 0 ? CornersForSkip(ds.BorderRadius, skip) : null); + bool rounded = roundedCorners is { } rc0 && + (rc0.TopLeft > 0 || rc0.TopRight > 0 || rc0.BottomRight > 0 || rc0.BottomLeft > 0); + + BitChartSvgNode shapeNode = rect; + if (rounded) shapeNode = new BitChartSvgPath { - D = RoundedRectPath(rect.X, rect.Y, rect.Width, rect.Height, ds.BorderRadiusCorners!.Value), + D = RoundedRectPath(rect.X, rect.Y, rect.Width, rect.Height, roundedCorners!.Value), Fill = bg }; // Border honoring borderSkipped. Rounded bars get a matching rounded border path so the // stroke follows the corner radius instead of cutting square corners. BitChartSvgNode? borderNode = null; - if (ds.BorderWidth > 0) + if (borderWidth > 0) { - if (roundedCorners is { } rc) + if (rounded) { borderNode = new BitChartSvgPath { - D = RoundedBarBorderPath(rect.X, rect.Y, rect.Width, rect.Height, rc, skip), - Fill = "none", Stroke = border, StrokeWidth = ds.BorderWidth + D = RoundedBarBorderPath(rect.X, rect.Y, rect.Width, rect.Height, roundedCorners!.Value, skip), + Fill = "none", Stroke = border, StrokeWidth = borderWidth }; } else if (skip == BitChartBorderSkipped.None) { rect.Stroke = border; - rect.StrokeWidth = ds.BorderWidth; + rect.StrokeWidth = borderWidth; } else { // Drawn as part of the element so it animates together with the fill. borderNode = new BitChartSvgPath { - D = BarBorderPath(rect, skip), Fill = "none", Stroke = border, StrokeWidth = ds.BorderWidth + D = BarBorderPath(rect, skip), Fill = "none", Stroke = border, StrokeWidth = borderWidth }; } } - string text = isRange - ? $"{(ds.Label is null ? "" : ds.Label + ": ")}[{baseVal.ToString("0.##", System.Globalization.CultureInfo.InvariantCulture)}, {topVal.ToString("0.##", System.Globalization.CultureInfo.InvariantCulture)}]" - : BuildItemText(ds, i, di, tooltipVal, bg); + // Hover appearance, precomputed so hovering never triggers a re-layout. + string hoverBg = ds.HoverBackgroundColor + ?? (ds.BackgroundColorFn is not null ? ResolveBackground(ds, i, di, false, tooltipVal, active: true) : BitChartColorUtil.Adjust(bg, -0.08)); + if (patternFill is not null) hoverBg = bg; + string hoverBorder = ds.HoverBorderColor ?? border; + double hoverBorderWidth = ds.HoverBorderWidth ?? borderWidth; + BitChartSvgNode hoverNode = rounded + ? new BitChartSvgPath + { + D = RoundedRectPath(rect.X, rect.Y, rect.Width, rect.Height, roundedCorners!.Value), + Fill = hoverBg, Stroke = hoverBorderWidth > 0 ? hoverBorder : null, StrokeWidth = hoverBorderWidth + } + : new BitChartSvgRect + { + X = rect.X, Y = rect.Y, Width = rect.Width, Height = rect.Height, + Fill = hoverBg, Stroke = hoverBorderWidth > 0 ? hoverBorder : null, StrokeWidth = hoverBorderWidth + }; - // Each bar grows from its own baseline in the correct direction (size change, not a slide). - string enterAnim = IsVertical ? "bc-scale-y" : "bc-scale-x"; + string text = isRange + ? $"{(ds.Label is null ? "" : ds.Label + ": ")}[{FormatNumber(baseVal, "0.##")}, {FormatNumber(topVal, "0.##")}]" + : BuildItemText(ds, i, di, tooltipVal, bg) + ErrorSuffix(ds, di); scene.Elements.Add(new BitChartDataElement { Shape = shapeNode, BorderShape = borderNode, - EnterAnim = enterAnim, - AnimOriginX = originX, - AnimOriginY = originY, + HoverShape = hoverNode, DatasetIndex = i, DataIndex = di, - CenterX = cx, - CenterY = cy, + CenterX = IsVertical ? cx : (rect.X + rect.Width / 2), + CenterY = IsVertical ? (rect.Y + rect.Height / 2) : cy, Value = tooltipVal, SeriesLabel = ds.Label, Tooltip = new BitChartTooltipInfo { Title = di < _data.Labels.Count ? _data.Labels[di] : null, + // Anchored at the bar's tip, so a negative bar points at its own end and the + // tooltip flips below it rather than hovering over the baseline. AnchorX = cx, - AnchorY = IsVertical ? Math.Min(rect.Y, cy) : cy, + AnchorY = cy, Items = { new BitChartTooltipItem { Color = bg, Text = text } } } }); - if (!isRange) AddDataLabel(scene, tooltipVal, cx, IsVertical ? rect.Y - 4 : cx, i, di); + if (!isRange) + { + // Centered on the bar's own tip, so a grouped bar keeps its whisker over itself. + // A percentage stack rescales every value, which would leave the interval - still in + // the original units - pointing at the wrong place, so it is left out there. + if (!stacked100) AddErrorBar(scene, ds, di, topVal, slotCenter, vScale); + AddBarDataLabel(scene, tooltipVal, rect, signFinal, i, di); + } } } } + /// The error bar attached to one index, if the dataset has one there. + private static BitChartErrorBar? ErrorAt(BitChartDataset ds, int dataIndex) + => ds.ErrorData is { } errors && dataIndex >= 0 && dataIndex < errors.Count ? errors[dataIndex] : null; + + /// + /// The interval a tooltip names after the value, so the uncertainty is readable and not only + /// visible. A symmetric interval reads as a single plus-minus; an asymmetric one names both arms. + /// + private string ErrorSuffix(BitChartDataset ds, int dataIndex) + { + if (ErrorAt(ds, dataIndex) is not { } e) return ""; + double minus = Math.Abs(e.Minus), plus = Math.Abs(e.Plus); + if (minus <= 0 && plus <= 0) return ""; + return e.IsSymmetric + ? $" ±{FormatNumber(plus, "0.##")}" + : $" +{FormatNumber(plus, "0.##")}/-{FormatNumber(minus, "0.##")}"; + } + + /// + /// Draws the whisker for one value: a line spanning the interval along the value axis, with a cap at + /// each end. It goes in the foreground so it stays legible over the bar or point it belongs to. + /// + private void AddErrorBar(BitChartScene scene, BitChartDataset ds, int dataIndex, double value, + double centerAlongIndexAxis, BitChartAxisScale valueScale) + { + if (ErrorAt(ds, dataIndex) is not { } e) return; + double minus = Math.Abs(e.Minus), plus = Math.Abs(e.Plus); + if (minus <= 0 && plus <= 0) return; + + double low = valueScale.PixelFor(value - minus); + double high = valueScale.PixelFor(value + plus); + string color = ds.ErrorBarColor ?? "var(--bit-clr-fg-pri, #1A1A1A)"; + double width = ds.ErrorBarWidth; + double cap = Math.Max(0, ds.ErrorBarCapWidth) / 2; + double c = centerAlongIndexAxis; + + if (IsVertical) + { + scene.Foreground.Add(new BitChartSvgLine { X1 = c, Y1 = low, X2 = c, Y2 = high, Stroke = color, StrokeWidth = width }); + if (cap <= 0) return; + scene.Foreground.Add(new BitChartSvgLine { X1 = c - cap, Y1 = low, X2 = c + cap, Y2 = low, Stroke = color, StrokeWidth = width }); + scene.Foreground.Add(new BitChartSvgLine { X1 = c - cap, Y1 = high, X2 = c + cap, Y2 = high, Stroke = color, StrokeWidth = width }); + } + else + { + scene.Foreground.Add(new BitChartSvgLine { X1 = low, Y1 = c, X2 = high, Y2 = c, Stroke = color, StrokeWidth = width }); + if (cap <= 0) return; + scene.Foreground.Add(new BitChartSvgLine { X1 = low, Y1 = c - cap, X2 = low, Y2 = c + cap, Stroke = color, StrokeWidth = width }); + scene.Foreground.Add(new BitChartSvgLine { X1 = high, Y1 = c - cap, X2 = high, Y2 = c + cap, Stroke = color, StrokeWidth = width }); + } + } + + private static bool HasValueAt(BitChartDataset ds, int di) + { + // A dataset carrying ranges still falls back to its plain values where a range is missing, + // which is exactly how DrawBars picks the value it draws. + if (ds.RangeData is { } rd && di < rd.Count && rd[di].HasValue) return true; + return di < ds.Data.Count && ds.Data[di].HasValue; + } + + /// Rounds only the corners that are not adjacent to the skipped edge (Chart.js semantics). + private static BitChartBorderRadiusCorners CornersForSkip(double r, BitChartBorderSkipped skip) => skip switch + { + BitChartBorderSkipped.Bottom => new(r, r, 0, 0), + BitChartBorderSkipped.Top => new(0, 0, r, r), + BitChartBorderSkipped.Left => new(0, r, r, 0), + BitChartBorderSkipped.Right => new(r, 0, 0, r), + _ => new(r, r, r, r) + }; + /// Resolves Start/End border-skip to a concrete edge based on orientation and sign. private static BitChartBorderSkipped ResolveSkip(BitChartBorderSkipped s, bool vertical, int sign) => s switch { @@ -317,39 +460,49 @@ private void DrawLine(BitChartScene scene, BitChartArea plot, BitChartAxisScale return; } + // A single fill paint is registered per dataset so a series broken by nulls does not add a + // duplicate gradient/pattern definition for every segment. + string? fillPaint = null; for (int di = 0; di < ds.Data.Count; di++) { if (ds.Data[di] is not { } v) { - if (!ds.SpanGaps) { FlushLine(scene, plot, vScale, ds, dsIndex, pts, indexScale, indexIsCategory, centered); pts.Clear(); } + if (!ds.SpanGaps) + { + fillPaint = FlushLine(scene, plot, vScale, ds, dsIndex, pts, indexScale, indexIsCategory, centered, fillPaint); + pts.Clear(); + } continue; } double x = indexIsCategory ? indexScale.PixelForIndex(di, centered) : indexScale.PixelFor(di); double y = vScale.PixelFor(v); pts.Add((x, y, di, v)); } - FlushLine(scene, plot, vScale, ds, dsIndex, pts, indexScale, indexIsCategory, centered); + FlushLine(scene, plot, vScale, ds, dsIndex, pts, indexScale, indexIsCategory, centered, fillPaint); } - private void FlushLine(BitChartScene scene, BitChartArea plot, BitChartAxisScale vScale, BitChartDataset ds, int dsIndex, + private string? FlushLine(BitChartScene scene, BitChartArea plot, BitChartAxisScale vScale, BitChartDataset ds, int dsIndex, List<(double x, double y, int di, double v)> pts, - BitChartAxisScale? indexScale = null, bool indexIsCategory = false, bool centered = false) + BitChartAxisScale? indexScale = null, bool indexIsCategory = false, bool centered = false, string? fillPaint = null) { - if (pts.Count == 0) return; + if (pts.Count == 0) return fillPaint; var dec = _options.Plugins.Decimation; if (dec.Enabled && pts.Count > dec.Threshold && dec.Samples >= 2 && dec.Samples < pts.Count) pts = BitChartDecimation.Lttb(pts, dec.Samples); string border = ResolveBorder(ds, dsIndex, 0, false); + double lineWidth = ResolveBorderWidth(ds, BitChartType.Line, dsIndex); + double tension = ResolveTension(ds); var xy = pts.Select(p => (p.x, p.y)).ToList(); - string d = BuildPath(xy, ds.Tension, ds.Stepped, ds.CubicInterpolationMode); + string d = BuildPath(xy, tension, ds.Stepped, ds.CubicInterpolationMode); bool progressive = _options.Animation.Animate && _options.Animation.Progressive; if (progressive) scene.ProgressiveDraw = true; if (ds.Fill != BitChartFillMode.None && ds.ShowLine) { + fillPaint ??= ResolveFill(scene, ds, border); string? fillD = null; // Fill to another dataset's line (range area). @@ -358,7 +511,7 @@ private void FlushLine(BitChartScene scene, BitChartArea plot, BitChartAxisScale { var target = ComputeLinePoints(_data.Datasets[ti], indexScale, vScale, indexIsCategory, centered); if (target.Count > 0) - fillD = AreaBetween(xy, ds.Tension, ds.Stepped, target.Select(p => (p.x, p.y)).ToList()); + fillD = AreaBetween(xy, tension, ds.Stepped, target.Select(p => (p.x, p.y)).ToList()); } if (fillD is null) @@ -374,7 +527,7 @@ private void FlushLine(BitChartScene scene, BitChartArea plot, BitChartAxisScale fillD = d + $" L {BitChartSvg.N(xy[^1].x)} {BitChartSvg.N(baseY)} L {BitChartSvg.N(xy[0].x)} {BitChartSvg.N(baseY)} Z"; } - scene.Series.Add(new BitChartSvgPath { D = fillD, Fill = ResolveFill(scene, ds, border, plot), Stroke = null, AnimateFade = progressive }); + scene.Series.Add(new BitChartSvgPath { D = fillD, Fill = fillPaint, Stroke = null, AnimateFade = progressive }); } if (ds.ShowLine) @@ -382,20 +535,20 @@ private void FlushLine(BitChartScene scene, BitChartArea plot, BitChartAxisScale if (ds.Segment is { } seg) { // Draw each consecutive segment with its own resolved style. - double defWidth = ds.BorderWidth <= 1 ? _options.Elements.LineBorderWidth : ds.BorderWidth; for (int k = 0; k < pts.Count - 1; k++) { var a = pts[k]; var b = pts[k + 1]; var sctx = new BitChartSegmentContext(a.di, b.di, a.v, b.v); string color = seg.BorderColor?.Invoke(sctx) ?? border; - double width = seg.BorderWidth?.Invoke(sctx) ?? defWidth; + double width = seg.BorderWidth?.Invoke(sctx) ?? lineWidth; var dash = seg.BorderDash?.Invoke(sctx); scene.Series.Add(new BitChartSvgPath { D = $"M {BitChartSvg.N(a.x)} {BitChartSvg.N(a.y)} L {BitChartSvg.N(b.x)} {BitChartSvg.N(b.y)}", Fill = "none", Stroke = color, StrokeWidth = width, Dash = dash is null ? "" : BitChartSvg.Dash(dash), + DashOffset = ds.BorderDashOffset, LineCap = ds.BorderCapStyle, LineJoin = ds.BorderJoinStyle, AnimateFade = progressive }); @@ -406,9 +559,9 @@ private void FlushLine(BitChartScene scene, BitChartArea plot, BitChartAxisScale bool dashed = ds.BorderDash is { Count: > 0 }; scene.Series.Add(new BitChartSvgPath { - D = d, Fill = "none", Stroke = border, - StrokeWidth = ds.BorderWidth <= 1 ? _options.Elements.LineBorderWidth : ds.BorderWidth, - Dash = BitChartSvg.Dash(ds.BorderDash), LineCap = ds.BorderCapStyle, LineJoin = ds.BorderJoinStyle, + D = d, Fill = "none", Stroke = border, StrokeWidth = lineWidth, + Dash = BitChartSvg.Dash(ds.BorderDash), DashOffset = ds.BorderDashOffset, + LineCap = ds.BorderCapStyle, LineJoin = ds.BorderJoinStyle, // Draw-on reveals the stroke left to right; dashed strokes can't (dasharray is in use), so they fade. AnimateDraw = progressive && !dashed, AnimateFade = progressive && dashed @@ -416,17 +569,25 @@ private void FlushLine(BitChartScene scene, BitChartArea plot, BitChartAxisScale } } - if (ds.PointRadius > 0 || ds.PointStyle != BitChartPointStyle.None) + if (ds.PointStyle != BitChartPointStyle.None) foreach (var p in pts) - AddPoint(scene, ds, dsIndex, p.di, p.x, p.y, p.v, ds.PointRadius, border); + AddPoint(scene, ds, dsIndex, p.di, p.x, p.y, p.v, ResolvePointRadius(ds), border, valueScale: vScale); + + return fillPaint; } - /// Resolves an area fill paint (pattern, gradient, explicit color, or translucent border). - private string ResolveFill(BitChartScene scene, BitChartDataset ds, string border, BitChartArea plot) + /// + /// Resolves an area fill paint. A pattern or gradient wins; then the dataset's explicit + /// , then its + /// (which is what Chart.js paints an area with), and finally a translucent tint of the line color. + /// + private string ResolveFill(BitChartScene scene, BitChartDataset ds, string border) { if (ds.BackgroundPattern is { } pat) return RegisterPattern(scene, pat); if (ds.FillGradient is { Stops.Count: > 0 } g) return RegisterGradient(scene, g); - return ds.FillColor ?? BitChartColorUtil.WithAlpha(border, 0.2); + if (!string.IsNullOrEmpty(ds.FillColor)) return ds.FillColor!; + if (!string.IsNullOrEmpty(ds.BackgroundColor)) return ds.BackgroundColor!; + return BitChartColorUtil.WithAlpha(border, 0.2); } /// Computes the pixel polyline for a dataset's line (nulls skipped). @@ -453,6 +614,7 @@ private string ResolveFill(BitChartScene scene, BitChartDataset ds, string borde private static string AreaBetween(List<(double x, double y)> top, double tension, BitChartSteppedLine stepped, List<(double x, double y)> bottom) { + if (bottom.Count == 0) return BuildPath(top, tension, stepped); var sb = new StringBuilder(BuildPath(top, tension, stepped)); var rev = new List<(double x, double y)>(bottom); rev.Reverse(); @@ -473,25 +635,42 @@ private void DrawStackedAreas(BitChartScene scene, BitChartArea plot, BitChartAx foreach (var group in items.GroupBy(t => (t.d.YAxisID, t.d.Stack ?? "default"))) { var vScale = valueScales[group.Key.YAxisID]; + bool stacked100 = vScale.Options.Stacked100; var cumulative = new Dictionary(); + // 100% stacking normalizes every index against the group's absolute total. + var totals = new Dictionary(); + if (stacked100) + foreach (var (ds, _) in group) + for (int di = 0; di < ds.Data.Count; di++) + if (ds.Data[di] is { } v) + totals[di] = totals.GetValueOrDefault(di, 0) + Math.Abs(v); + foreach (var (ds, i) in group) { - var topPts = new List<(double x, double y, int di, double v)>(); + var topPts = new List<(double x, double y, int di, double v, double top)>(); var basePts = new List<(double x, double y)>(); for (int di = 0; di < ds.Data.Count; di++) { - if (ds.Data[di] is not { } v) continue; + if (ds.Data[di] is not { } raw) continue; + double v = raw; + if (stacked100) + { + double total = totals.GetValueOrDefault(di, 0); + if (total > 0) v = v / total * 100; + } double baseVal = cumulative.GetValueOrDefault(di, 0); double topVal = baseVal + v; cumulative[di] = topVal; double x = indexIsCategory ? indexScale.PixelForIndex(di, centered) : indexScale.PixelFor(di); - topPts.Add((x, vScale.PixelFor(topVal), di, topVal)); + topPts.Add((x, vScale.PixelFor(topVal), di, raw, topVal)); basePts.Add((x, vScale.PixelFor(baseVal))); } if (topPts.Count == 0) continue; string border = ResolveBorder(ds, i, 0, false); + double lineWidth = ResolveBorderWidth(ds, BitChartType.Line, i); + double tension = ResolveTension(ds); var topXy = topPts.Select(p => (p.x, p.y)).ToList(); bool progressive = _options.Animation.Animate && _options.Animation.Progressive; @@ -500,22 +679,28 @@ private void DrawStackedAreas(BitChartScene scene, BitChartArea plot, BitChartAx if (ds.Fill != BitChartFillMode.None) { - string fillD = AreaBetween(topXy, ds.Tension, ds.Stepped, basePts); - scene.Series.Add(new BitChartSvgPath { D = fillD, Fill = ResolveFill(scene, ds, border, plot), Stroke = null, AnimateFade = progressive }); + string fillD = AreaBetween(topXy, tension, ds.Stepped, basePts); + scene.Series.Add(new BitChartSvgPath { D = fillD, Fill = ResolveFill(scene, ds, border), Stroke = null, AnimateFade = progressive }); } scene.Series.Add(new BitChartSvgPath { - D = BuildPath(topXy, ds.Tension, ds.Stepped), Fill = "none", Stroke = border, - StrokeWidth = ds.BorderWidth <= 1 ? _options.Elements.LineBorderWidth : ds.BorderWidth, - Dash = BitChartSvg.Dash(ds.BorderDash), LineCap = ds.BorderCapStyle, LineJoin = ds.BorderJoinStyle, + D = BuildPath(topXy, tension, ds.Stepped, ds.CubicInterpolationMode), Fill = "none", Stroke = border, + StrokeWidth = lineWidth, + Dash = BitChartSvg.Dash(ds.BorderDash), DashOffset = ds.BorderDashOffset, + LineCap = ds.BorderCapStyle, LineJoin = ds.BorderJoinStyle, AnimateDraw = progressive && !dashed, AnimateFade = progressive && dashed }); - if (ds.PointRadius > 0) + if (ds.PointStyle != BitChartPointStyle.None) foreach (var p in topPts) - AddPoint(scene, ds, i, p.di, p.x, p.y, ds.Data[p.di] ?? 0, ds.PointRadius, border); + // The marker sits at the cumulative top, so the whisker is centered there too + // rather than at the raw value it is drawn from. A percentage stack rescales + // every value, which would leave the interval - still in the original units - + // pointing at the wrong place, so it is left out there. + AddPoint(scene, ds, i, p.di, p.x, p.y, p.v, ResolvePointRadius(ds), border, + valueScale: stacked100 ? null : vScale, errorValue: p.top); } } } @@ -530,46 +715,50 @@ private void DrawScatter(BitChartScene scene, BitChartArea plot, BitChartAxisSca var p = points[di]; double x = indexScale.PixelFor(p.X); double y = vScale.PixelFor(p.Y); - double r = bubble ? (p.R ?? 5) : ds.PointRadius <= 3 ? 4 : ds.PointRadius; - AddPoint(scene, ds, dsIndex, di, x, y, p.Y, r, border, p.X); + double r = bubble ? (p.R ?? 5) : Math.Max(4, ResolvePointRadius(ds)); + AddPoint(scene, ds, dsIndex, di, x, y, p.Y, r, border, p.X, vScale); } } private void AddPoint(BitChartScene scene, BitChartDataset ds, int dsIndex, int di, - double x, double y, double value, double radius, string border, double? xValue = null) + double x, double y, double value, double radius, string border, double? xValue = null, + BitChartAxisScale? valueScale = null, double? errorValue = null) { var ctx = Ctx(ds, dsIndex, di, value); - bool active = _state.Active == (dsIndex, di); - double r = ds.PointRadiusFn?.Invoke(ctx) ?? radius; var style = ds.PointStyleFn?.Invoke(ctx) ?? ds.PointStyle; string fill = ds.PointBackgroundColorFn?.Invoke(ctx) ?? ds.PointBackgroundColor ?? ResolveBackground(ds, dsIndex, di, false, value); string stroke = ds.PointBorderColorFn?.Invoke(ctx) ?? ds.PointBorderColor ?? border; double bw = ds.PointBorderWidth; - if (active) - { - r = Math.Max(r, ds.PointHoverRadius); - if (ds.PointHoverBackgroundColor is { } hb) fill = hb; - if (ds.PointHoverBorderColor is { } hbc) stroke = hbc; - if (ds.PointHoverBorderWidth is { } hbw) bw = hbw; - } - - var shape = BitChartPointShapes.Build(style, x, y, r, fill, stroke, bw); - if (shape is null) return; - - bool cartesian = _config.Type is not (BitChartType.Pie or BitChartType.Doughnut or BitChartType.PolarArea or BitChartType.Radar); - - string text = xValue is { } xv - ? $"({xv.ToString("0.##", System.Globalization.CultureInfo.InvariantCulture)}, {value.ToString("0.##", System.Globalization.CultureInfo.InvariantCulture)})" - : BuildItemText(ds, dsIndex, di, value, fill); + // A marker that is hidden or has no radius still needs something to hover: an invisible hit disc + // keeps the data point reachable (this is what Chart.js's pointHitRadius does). + BitChartSvgNode? shape = r > 0 ? BitChartPointShapes.Build(style, x, y, r, fill, stroke, bw, ds.PointRotation) : null; + double hitR = Math.Max(ds.HitRadius, 4); + shape ??= new BitChartSvgCircle { Cx = x, Cy = y, R = hitR, Fill = "transparent" }; + + // The hover appearance is precomputed with Active = true so scriptable options can react to it. + var hctx = Ctx(ds, dsIndex, di, value, active: true); + double hr = Math.Max(ds.PointRadiusFn?.Invoke(hctx) ?? r, ds.PointHoverRadius); + string hFill = ds.PointHoverBackgroundColor ?? ds.PointBackgroundColorFn?.Invoke(hctx) ?? fill; + string hStroke = ds.PointHoverBorderColor ?? ds.PointBorderColorFn?.Invoke(hctx) ?? stroke; + double hbw = ds.PointHoverBorderWidth ?? Math.Max(bw, 2); + var hoverShape = BitChartPointShapes.Build(style == BitChartPointStyle.None ? BitChartPointStyle.Circle : style, + x, y, Math.Max(hr, 3), hFill, hStroke, hbw, ds.PointRotation); + + string text = (xValue is { } xv + ? $"({FormatNumber(xv, "0.##")}, {FormatNumber(value, "0.##")})" + : BuildItemText(ds, dsIndex, di, value, fill)) + ErrorSuffix(ds, di); + + // A whisker needs the value axis to convert its interval, so it is only drawn where the caller + // could hand one over - which is every cartesian call site, but not the radar's. + if (valueScale is not null) + AddErrorBar(scene, ds, di, errorValue ?? value, IsVertical ? x : y, valueScale); scene.Elements.Add(new BitChartDataElement { Shape = shape, - EnterAnim = cartesian ? "bc-pop" : null, - AnimOriginX = x, - AnimOriginY = y, + HoverShape = hoverShape, DatasetIndex = dsIndex, DataIndex = di, CenterX = x, @@ -584,6 +773,75 @@ private void AddPoint(BitChartScene scene, BitChartDataset ds, int dsIndex, int Items = { new BitChartTooltipItem { Color = fill, Text = text, PointStyle = style } } } }); + + if (_options.Plugins.DataLabels is { Display: true, ShowOnPoints: true }) + AddPointDataLabel(scene, value, x, y, r, dsIndex, di); + } + + /// Places a bar's data label from the anchor/align/offset options. + private void AddBarDataLabel(BitChartScene scene, double value, BitChartSvgRect rect, int sign, int dsIndex, int dataIndex) + { + var dl = _options.Plugins.DataLabels; + if (!dl.Display) return; + + // Outward is the direction away from the baseline: up for positive vertical bars, right for + // positive horizontal ones. + double x, y; + if (IsVertical) + { + double tip = sign >= 0 ? rect.Y : rect.Y + rect.Height; + double baseline = sign >= 0 ? rect.Y + rect.Height : rect.Y; + double outward = sign >= 0 ? -1 : 1; + y = dl.Anchor switch + { + BitChartAlign.Start => baseline, + BitChartAlign.Center => rect.Y + rect.Height / 2, + _ => tip + }; + y += AlignShift(dl, outward); + x = rect.X + rect.Width / 2; + } + else + { + double tip = sign >= 0 ? rect.X + rect.Width : rect.X; + double baseline = sign >= 0 ? rect.X : rect.X + rect.Width; + double outward = sign >= 0 ? 1 : -1; + x = dl.Anchor switch + { + BitChartAlign.Start => baseline, + BitChartAlign.Center => rect.X + rect.Width / 2, + _ => tip + }; + x += AlignShift(dl, outward); + y = rect.Y + rect.Height / 2; + } + AddDataLabel(scene, value, x, y, dsIndex, dataIndex); + } + + /// Places a point's data label from the anchor/align/offset options (default: above the marker). + private void AddPointDataLabel(BitChartScene scene, double value, double x, double y, double radius, int dsIndex, int dataIndex) + { + var dl = _options.Plugins.DataLabels; + double anchorY = dl.Anchor switch + { + BitChartAlign.Start => y + radius, + BitChartAlign.Center => y, + _ => y - radius + }; + double outward = dl.Anchor == BitChartAlign.Start ? 1 : -1; + AddDataLabel(scene, value, x, anchorY + AlignShift(dl, outward), dsIndex, dataIndex); + } + + /// How far (and in which direction) the label sits from its anchor. + private static double AlignShift(BitChartDataLabelOptions dl, double outward) + { + double dist = dl.Offset + dl.Font.Size * 0.5 + dl.Padding; + return dl.Align switch + { + BitChartAlign.End => outward * dist, + BitChartAlign.Start => -outward * dist, + _ => 0 + }; } private void AddDataLabel(BitChartScene scene, double value, double x, double y, int dsIndex = 0, int dataIndex = 0) @@ -594,15 +852,21 @@ private void AddDataLabel(BitChartScene scene, double value, double x, double y, string text = dl.FormatterCtx?.Invoke(value, dsIndex, dataIndex) ?? dl.Formatter?.Invoke(value) - ?? value.ToString("0.##", System.Globalization.CultureInfo.InvariantCulture); + ?? FormatNumber(value, "0.##"); + + // Kept inside the content box: a label pushed past the tip of a bar at the top of the axis + // would otherwise be clipped by the edge of the chart. + double halfW = BitChartTextMeasure.Width(text, dl.Font.Size, dl.Font.Weight) / 2 + dl.Padding; + double halfH = dl.Font.Size / 2 + dl.Padding; + var box = ContentArea(); + if (box.Width > halfW * 2) x = Math.Clamp(x, box.Left + halfW, box.Right - halfW); + if (box.Height > halfH * 2) y = Math.Clamp(y, box.Top + halfH, box.Bottom - halfH); if (dl.BackgroundColor is { } bgc) { - double w = BitChartTextMeasure.Width(text, dl.Font.Size, dl.Font.Weight) + dl.Padding * 2; - double h = dl.Font.Size + dl.Padding * 2; scene.Foreground.Add(new BitChartSvgRect { - X = x - w / 2, Y = y - h / 2, Width = w, Height = h, Rx = dl.BorderRadius, Fill = bgc + X = x - halfW, Y = y - halfH, Width = halfW * 2, Height = halfH * 2, Rx = dl.BorderRadius, Fill = bgc }); } @@ -611,7 +875,7 @@ private void AddDataLabel(BitChartScene scene, double value, double x, double y, X = x, Y = y, Text = text, Fill = dl.Color, FontFamily = dl.Font.Family, FontSize = dl.Font.Size, FontWeight = dl.Font.Weight, - Anchor = "middle", Baseline = dl.BackgroundColor is null ? "auto" : "central", Rotation = dl.Rotation + Anchor = "middle", Baseline = "central", Rotation = dl.Rotation }); } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.cs index a4c97eb3a4..5dfdbbe98c 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartRenderer.cs @@ -1,3 +1,4 @@ +using System.Globalization; namespace Bit.BlazorUI; @@ -14,8 +15,16 @@ public sealed partial class BitChartRenderer private readonly BitChartRenderState _state; private readonly double _w; private readonly double _h; + private readonly string _uid; - public BitChartRenderer(BitChartConfig config, BitChartRenderState state, double width, double height) + /// + /// The scales actually used for this render. Seeded from and + /// completed with defaults here, so the caller's options object is never mutated and can safely be + /// shared between charts of different types. + /// + private readonly Dictionary _scales = new(); + + public BitChartRenderer(BitChartConfig config, BitChartRenderState state, double width, double height, string? uid = null) { _config = config; _data = config.Data; @@ -23,6 +32,7 @@ public BitChartRenderer(BitChartConfig config, BitChartRenderState state, double _state = state; _w = width; _h = height; + _uid = uid ?? "bc"; } public BitChartScene Render() @@ -50,25 +60,34 @@ public BitChartScene Render() } BuildLegend(scene); + scene.IsEmpty = scene.Elements.Count == 0 && scene.Series.Count == 0; return scene; } // ---- shared helpers ---- - private int _gradSeq; + private int _defSeq; + + /// The culture every number/date is formatted with (invariant unless the caller opts in). + private CultureInfo Culture => _options.Culture ?? CultureInfo.InvariantCulture; + + /// Formats a data value the way tooltips and data labels present it. + private string FormatNumber(double value, string format = "0.###") => value.ToString(format, Culture); - /// Registers a gradient on the scene and returns a url(#id) fill reference. + /// Registers a gradient on the scene and returns a url(#id) fill reference. + /// Ids are namespaced per chart instance so several charts can share a page. private string RegisterGradient(BitChartScene scene, BitChartGradientBase grad) { - string id = $"bcgrad{_gradSeq++}"; + string id = $"{_uid}-g{_defSeq++}"; scene.Defs.Add(new BitChartGradientDef(id, grad)); return $"url(#{id})"; } - /// Registers a pattern on the scene and returns a url(#id) fill reference. + /// Registers a pattern on the scene and returns a url(#id) fill reference. + /// Ids are namespaced per chart instance so several charts can share a page. private string RegisterPattern(BitChartScene scene, BitChartFillPattern pattern) { - string id = $"bcpat{_gradSeq++}"; + string id = $"{_uid}-p{_defSeq++}"; scene.Patterns.Add(new BitChartPatternDef(id, pattern)); return $"url(#{id})"; } @@ -83,21 +102,19 @@ private BitChartArea ContentArea() } /// Builds a scriptable-options context for a data element. - private BitChartScriptableContext Ctx(BitChartDataset ds, int dsIndex, int dataIndex, double? value = null) + private BitChartScriptableContext Ctx(BitChartDataset ds, int dsIndex, int dataIndex, double? value = null, bool active = false) { - bool active = _state.Active == (dsIndex, dataIndex); double? v = value; double? vx = null, vr = null; - if (v is null) + if (ds.Points is { } pts && dataIndex < pts.Count) { - if (ds.Points is { } pts && dataIndex < pts.Count) - { - v = pts[dataIndex].Y; vx = pts[dataIndex].X; vr = pts[dataIndex].R; - } - else if (dataIndex < ds.Data.Count) - { - v = ds.Data[dataIndex]; - } + vx = pts[dataIndex].X; + vr = pts[dataIndex].R; + v ??= pts[dataIndex].Y; + } + else if (v is null && dataIndex < ds.Data.Count) + { + v = ds.Data[dataIndex]; } return new BitChartScriptableContext { @@ -114,32 +131,68 @@ private BitChartScriptableContext Ctx(BitChartDataset ds, int dsIndex, int dataI } /// Resolves the effective color for a data element, honoring dataset palettes. - private string ResolveBackground(BitChartDataset ds, int dsIndex, int dataIndex, bool perIndexPalette, double? value = null) + private string ResolveBackground(BitChartDataset ds, int dsIndex, int dataIndex, bool perIndexPalette, double? value = null, bool active = false) { - if (ds.BackgroundColorFn is { } fn && fn(Ctx(ds, dsIndex, dataIndex, value)) is { } c) return c; + if (ds.BackgroundColorFn is { } fn && fn(Ctx(ds, dsIndex, dataIndex, value, active)) is { } c) return c; if (ds.BackgroundColors is { Count: > 0 } list) - return list[dataIndex % list.Count]; + return list[((dataIndex % list.Count) + list.Count) % list.Count]; if (!string.IsNullOrEmpty(ds.BackgroundColor)) return ds.BackgroundColor!; return perIndexPalette ? BitChartColorUtil.Palette(dataIndex) : BitChartColorUtil.Palette(dsIndex); } - private string ResolveBorder(BitChartDataset ds, int dsIndex, int dataIndex, bool perIndexPalette, double? value = null) + /// + /// Resolves the border color of an element. is used by the + /// filled element types (bars, arcs): with no explicit border color they take the fill color rather + /// than an unrelated palette entry, which would otherwise outline them in a different hue. + /// + private string ResolveBorder(BitChartDataset ds, int dsIndex, int dataIndex, bool perIndexPalette, + double? value = null, bool fallbackToBackground = false, bool active = false) { - if (ds.BorderColorFn is { } fn && fn(Ctx(ds, dsIndex, dataIndex, value)) is { } c) return c; + if (ds.BorderColorFn is { } fn && fn(Ctx(ds, dsIndex, dataIndex, value, active)) is { } c) return c; if (ds.BorderColors is { Count: > 0 } list) - return list[dataIndex % list.Count]; + return list[((dataIndex % list.Count) + list.Count) % list.Count]; if (!string.IsNullOrEmpty(ds.BorderColor)) return ds.BorderColor!; + if (fallbackToBackground) + return ResolveBackground(ds, dsIndex, dataIndex, perIndexPalette, value, active); return perIndexPalette ? BitChartColorUtil.Palette(dataIndex) : BitChartColorUtil.Palette(dsIndex); } + /// True when the dataset asks for a border color in any form. + private static bool HasExplicitBorder(BitChartDataset ds) + => ds.BorderColorFn is not null || ds.BorderColors is { Count: > 0 } || !string.IsNullOrEmpty(ds.BorderColor); + + /// + /// Resolves the border/line width for a dataset, falling back to the per-type defaults on + /// when the dataset leaves unset. + /// + private double ResolveBorderWidth(BitChartDataset ds, BitChartType type, int dsIndex = 0, int dataIndex = 0, double? value = null, bool active = false) + { + if (active && ds.HoverBorderWidth is { } hbw) return hbw; + if (ds.BorderWidthFn is { } fn && fn(Ctx(ds, dsIndex, dataIndex, value, active)) is { } w) return w; + if (ds.BorderWidth is { } bw) return bw; + var e = _options.Elements; + return type switch + { + BitChartType.Bar => HasExplicitBorder(ds) ? Math.Max(e.BarBorderWidth, 1) : e.BarBorderWidth, + BitChartType.Pie or BitChartType.Doughnut or BitChartType.PolarArea => e.ArcBorderWidth, + _ => e.LineBorderWidth + }; + } + + /// Marker radius for a dataset, falling back to the element default. + private double ResolvePointRadius(BitChartDataset ds) => ds.PointRadius ?? _options.Elements.PointRadius; + + /// Line smoothing for a dataset, falling back to the element default. + private double ResolveTension(BitChartDataset ds) => ds.Tension ?? _options.Elements.LineTension; + private string FormatTooltipValue(BitChartDataset ds, double value) { var t = _options.Plugins.Tooltip; if (t.LabelFormatter is { } f) return f(ds.Label ?? "", value); string label = string.IsNullOrEmpty(ds.Label) ? "" : ds.Label + ": "; - return label + value.ToString("0.###", System.Globalization.CultureInfo.InvariantCulture); + return label + FormatNumber(value); } /// Builds a tooltip item context for callbacks. @@ -155,7 +208,7 @@ private BitChartTooltipItemContext BuildTooltipItem(BitChartDataset ds, int dsIn Value = value, ValueX = vx, Color = color, - FormattedValue = value.ToString("0.###", System.Globalization.CultureInfo.InvariantCulture) + FormattedValue = FormatNumber(value) }; } @@ -168,56 +221,99 @@ private string BuildItemText(BitChartDataset ds, int dsIndex, int dataIndex, dou return FormatTooltipValue(ds, value); } + // ---- scales ---- + + /// The scale options for an id within this render (never null once EnsureScales has run). + private BitChartScaleOptions Scale(string id) => _scales[id]; + + /// + /// The radial scale a radar or polar-area chart reads. One radial scale serves the whole chart, so + /// it is the first dataset's that names it. + /// + private string RadialScaleId + { + get + { + var ds = _data.Datasets.FirstOrDefault(d => !string.IsNullOrEmpty(d.RAxisID)); + return ds?.RAxisID ?? "r"; + } + } + + /// + /// Whether a scale draws itself. A sparkline is defined by having no chrome at all, so it silences + /// every axis here rather than asking each caller to remember the option. + /// + private bool ScaleVisible(BitChartScaleOptions o) => o.Display && !_options.Sparkline; + + /// Whether a radial scale draws the category labels around its perimeter. + private bool PointLabelsVisible(BitChartScaleOptions o) => o.PointLabels.Display && !_options.Sparkline; + + /// Effective position of a scale, without writing the default back onto the caller's object. + private static BitChartPosition PositionOf(BitChartScaleOptions o, BitChartPosition fallback) => o.Position ?? fallback; + + /// Returns the caller's scale for an id, or a fresh default one - added to the local map only. + private BitChartScaleOptions GetOrAddScale(string id, BitChartScaleType type) + { + if (_scales.TryGetValue(id, out var s)) return s; + if (_options.Scales.TryGetValue(id, out var user)) + { + _scales[id] = user; + return user; + } + s = new BitChartScaleOptions { Id = id, Type = type }; + _scales[id] = s; + return s; + } + private void EnsureScales() { + _scales.Clear(); + foreach (var (id, so) in _options.Scales) _scales[id] = so; + if (_config.Type is BitChartType.Pie or BitChartType.Doughnut) return; if (_config.Type is BitChartType.PolarArea or BitChartType.Radar) { - _options.GetOrAddScale("r", BitChartScaleType.RadialLinear); + GetOrAddScale(RadialScaleId, BitChartScaleType.RadialLinear); return; } // Cartesian: ensure x and y exist with sensible defaults. - var x = _options.GetOrAddScale("x", _config.Type is BitChartType.Scatter or BitChartType.Bubble + GetOrAddScale("x", _config.Type is BitChartType.Scatter or BitChartType.Bubble ? BitChartScaleType.Linear : BitChartScaleType.Category); - x.Position ??= BitChartPosition.Bottom; - // Additional x axes referenced by datasets (default linear, bottom). + // Additional x axes referenced by datasets (default linear). foreach (var id in _data.Datasets.Select(d => d.XAxisID).Distinct()) { if (id == "x" || string.IsNullOrEmpty(id)) continue; - var x2 = _options.GetOrAddScale(id, BitChartScaleType.Linear); - x2.Position ??= BitChartPosition.Bottom; + GetOrAddScale(id, BitChartScaleType.Linear); } // Gather y axis ids referenced by datasets. - var yIds = _data.Datasets.Select(d => d.YAxisID).Distinct().ToList(); - foreach (var id in yIds) - { - var y = _options.GetOrAddScale(id, BitChartScaleType.Linear); - y.Position ??= BitChartPosition.Left; - } - if (!_options.Scales.ContainsKey("y")) + foreach (var id in _data.Datasets.Select(d => d.YAxisID).Distinct()) { - var y = _options.GetOrAddScale("y", BitChartScaleType.Linear); - y.Position ??= BitChartPosition.Left; + if (string.IsNullOrEmpty(id)) continue; + GetOrAddScale(id, BitChartScaleType.Linear); } + GetOrAddScale("y", BitChartScaleType.Linear); } private void BuildLegend(BitChartScene scene) { var lo = _options.Plugins.Legend; - if (!lo.Display) return; + if (!lo.Display || _options.Sparkline) return; var legend = new BitChartLegendModel { - Position = lo.Position, + // The legend only has four sides to live on; anything else would silently render nowhere. + Position = lo.Position is BitChartPosition.Bottom or BitChartPosition.Left or BitChartPosition.Right + ? lo.Position : BitChartPosition.Top, Align = lo.Align, Labels = lo.Labels, Title = lo.Title, - OnClickToggle = lo.OnClickToggle + OnClickToggle = lo.OnClickToggle, + MaxHeight = lo.MaxHeight }; if (_config.Type is BitChartType.Pie or BitChartType.Doughnut or BitChartType.PolarArea) @@ -257,20 +353,23 @@ private void BuildLegend(BitChartScene scene) } } + if (lo.Filter is { } filter) + legend.Items.RemoveAll(it => !filter(it)); if (lo.Reverse) legend.Items.Reverse(); scene.Legend = legend; } private BitChartTitleModel? BuildTitle(BitChartTitleOptions o) { - if (!o.Display || string.IsNullOrEmpty(o.Text)) return null; + if (!o.Display || _options.Sparkline || string.IsNullOrEmpty(o.Text)) return null; return new BitChartTitleModel { Text = o.Text, Color = o.Color, Position = o.Position, Align = o.Align, - Font = o.Font + Font = o.Font, + Padding = o.Padding }; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartScene.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartScene.cs index f087cf4df1..61994c16d1 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartScene.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartScene.cs @@ -12,6 +12,8 @@ public sealed class BitChartScene /// Rendered in an animated group so every line - solid, dashed or per-segment - animates uniformly. public List Series { get; } = new(); public List Elements { get; } = new(); + /// Invisible per-index hit areas spanning the plot, used for non-intersecting hover. + public List HitBands { get; } = new(); public List Foreground { get; } = new(); /// Gradient definitions referenced via url(#id). @@ -45,4 +47,20 @@ public sealed class BitChartScene public Dictionary AxisRanges { get; } = new(); /// Axis ids that support zoom/pan (linear/time/logarithmic). public HashSet ZoomableAxes { get; } = new(); + /// The full (un-zoomed) data range per axis id, used to keep zoom/pan inside the data. + public Dictionary DataRanges { get; } = new(); + + /// Axis ids drawn in reverse, so pointer gestures can be mapped back the right way round. + public HashSet ReversedAxes { get; } = new(); + + /// + /// How each axis is laid out, which is what lets a pointer gesture be mapped back onto it. An axis + /// runs across the plot or down it depending on the chart's index axis - the value axes of a + /// horizontal-bar chart are the horizontal ones - and a vertical value axis additionally has its + /// minimum at the bottom, i.e. at the far pixel rather than the near one. + /// + public Dictionary AxisOrientations { get; } = new(); + + /// True when the configuration produced nothing to draw (no datasets, or all empty/hidden). + public bool IsEmpty { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartSvgNode.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartSvgNode.cs index 17c69c405d..fa1746ad61 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartSvgNode.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartSvgNode.cs @@ -3,7 +3,10 @@ namespace Bit.BlazorUI; /// Base class for renderable SVG primitives produced by the renderer. public abstract class BitChartSvgNode { + /// Native SVG tooltip text, rendered as a child <title> element. public string? Title { get; set; } public double Opacity { get; set; } = 1; public string? CssClass { get; set; } + /// Optional SVG transform applied to the primitive (e.g. a marker rotation). + public string? Transform { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartSvgPath.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartSvgPath.cs index 9e52d19a22..5f439fd64a 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartSvgPath.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartSvgPath.cs @@ -7,6 +7,7 @@ public sealed class BitChartSvgPath : BitChartSvgNode public string? Stroke; public double StrokeWidth = 0; public string? Dash; + public double DashOffset; public string LineCap = "butt"; public string LineJoin = "miter"; /// When true the path animates a "draw-on" effect via stroke-dashoffset. diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTextMeasure.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTextMeasure.cs index c713180d70..535074d37d 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTextMeasure.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTextMeasure.cs @@ -1,3 +1,5 @@ +using System.Globalization; + namespace Bit.BlazorUI; /// @@ -39,13 +41,45 @@ public static double Width(string? text, double fontSize, string weight = "norma if (string.IsNullOrEmpty(text)) return 0; double em = 0; foreach (char c in text) - em += Widths.TryGetValue(c, out var w) ? w : Default; + em += Advance(c); // Bold text is a touch wider. bool bold = weight is "bold" or "600" or "700" or "800" or "900"; if (bold) em *= 1.06; return em * fontSize; } + /// + /// How wide one character is, as a fraction of the font size. The table above covers Latin; beyond + /// it, a CJK, Kana or Hangul glyph is a full em rather than the Latin average - assuming otherwise + /// under-measures a Japanese axis label by nearly half, and the axis then reserves too little space + /// and the labels collide. A combining mark sits on the glyph before it and adds nothing. + /// + private static double Advance(char c) + { + if (Widths.TryGetValue(c, out var w)) return w; + if (IsFullWidth(c)) return 1; + return CharUnicodeInfo.GetUnicodeCategory(c) switch + { + UnicodeCategory.NonSpacingMark or UnicodeCategory.EnclosingMark => 0, + UnicodeCategory.Format or UnicodeCategory.Control => 0, + _ => Default + }; + } + + /// The blocks whose glyphs are drawn on a full-width em square. + private static bool IsFullWidth(char c) => + c is >= 'ᄀ' and <= 'ᅟ' // Hangul Jamo + or >= '⺀' and <= '〾' // CJK radicals, Kangxi, CJK symbols and punctuation + or >= 'ぁ' and <= '㏿' // Kana, Bopomofo, Hangul compatibility Jamo, CJK compatibility + or >= '㐀' and <= '䶿' // CJK extension A + or >= '一' and <= '鿿' // CJK unified ideographs + or >= 'ꀀ' and <= '꓏' // Yi + or >= '가' and <= '힣' // Hangul syllables + or >= '豈' and <= '﫿' // CJK compatibility ideographs + or >= '︰' and <= '﹯' // CJK compatibility forms, small form variants + or >= '＀' and <= '⦆' // Full-width forms + or >= '¢' and <= '₩'; // Full-width signs + /// Width of the widest line in a multi-line string. public static double MultilineWidth(string? text, double fontSize, string weight = "normal") { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTimeAxis.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTimeAxis.cs index b429215e50..10165de5d8 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTimeAxis.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTimeAxis.cs @@ -21,18 +21,27 @@ public static BitChartTimeUnit ChooseUnit(DateTime min, DateTime max) return BitChartTimeUnit.Year; } - public static string DefaultFormat(DateTime d, BitChartTimeUnit unit) => unit switch + /// + /// The label a tick gets when the caller supplies no formatter. Month and day names come from the + /// chart's culture, so a localized chart does not end up printing French numbers next to English + /// months; the invariant culture is the default, which keeps output stable. + /// + public static string DefaultFormat(DateTime d, BitChartTimeUnit unit, CultureInfo? culture = null) { - BitChartTimeUnit.Millisecond => d.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture), - BitChartTimeUnit.Second => d.ToString("HH:mm:ss", CultureInfo.InvariantCulture), - BitChartTimeUnit.Minute => d.ToString("HH:mm", CultureInfo.InvariantCulture), - BitChartTimeUnit.Hour => d.ToString("HH:mm", CultureInfo.InvariantCulture), - BitChartTimeUnit.Day => d.ToString("MMM d", CultureInfo.InvariantCulture), - BitChartTimeUnit.Week => d.ToString("MMM d", CultureInfo.InvariantCulture), - BitChartTimeUnit.Month => d.ToString("MMM yyyy", CultureInfo.InvariantCulture), - BitChartTimeUnit.Quarter => $"Q{(d.Month - 1) / 3 + 1} {d.Year}", - _ => d.Year.ToString(CultureInfo.InvariantCulture) - }; + var c = culture ?? CultureInfo.InvariantCulture; + return unit switch + { + BitChartTimeUnit.Millisecond => d.ToString("HH:mm:ss.fff", c), + BitChartTimeUnit.Second => d.ToString("HH:mm:ss", c), + BitChartTimeUnit.Minute => d.ToString("HH:mm", c), + BitChartTimeUnit.Hour => d.ToString("HH:mm", c), + BitChartTimeUnit.Day => d.ToString("MMM d", c), + BitChartTimeUnit.Week => d.ToString("MMM d", c), + BitChartTimeUnit.Month => d.ToString("MMM yyyy", c), + BitChartTimeUnit.Quarter => $"Q{(d.Month - 1) / 3 + 1} {d.Year.ToString(c)}", + _ => d.Year.ToString(c) + }; + } private static DateTime Floor(DateTime d, BitChartTimeUnit unit) => unit switch { @@ -46,6 +55,24 @@ public static BitChartTimeUnit ChooseUnit(DateTime min, DateTime max) _ => new DateTime(d.Year, 1, 1) }; + /// + /// Advances a tick by one step, saturating at . Returns false when it + /// could not move, which is what stops the tick loops at the end of the calendar instead of throwing + /// or spinning. + /// + private static bool TryNext(DateTime d, BitChartTimeUnit unit, int step, out DateTime next) + { + try + { + next = Next(d, unit, step); + } + catch (ArgumentOutOfRangeException) + { + next = DateTime.MaxValue; + } + return next > d; + } + private static DateTime Next(DateTime d, BitChartTimeUnit unit, int step) => unit switch { BitChartTimeUnit.Millisecond => d.AddMilliseconds(step), @@ -59,19 +86,33 @@ public static BitChartTimeUnit ChooseUnit(DateTime min, DateTime max) _ => d.AddYears(step) }; + /// The OLE Automation date range accepts. + private const double MinOaDate = -657434.0; + private const double MaxOaDate = 2958465.99999999; + + /// + /// Converts an axis value to a date. Values outside the OLE Automation range - a time scale pointed + /// at data that is not dates - are clamped instead of throwing out of the render. + /// + private static DateTime ToDate(double oa) + => DateTime.FromOADate(Math.Clamp(double.IsFinite(oa) ? oa : 0, MinOaDate, MaxOaDate)); + /// Generates (oaDateValue, label) ticks between min and max. public static List<(double Value, string Label)> Ticks(double minOa, double maxOa, BitChartTimeUnit unit, - Func? format, int maxTicks = 11) + Func? format, int maxTicks = 11, CultureInfo? culture = null) { - var min = DateTime.FromOADate(minOa); - var max = DateTime.FromOADate(maxOa); + var min = ToDate(minOa); + var max = ToDate(maxOa); + if (max < min) (min, max) = (max, min); if (unit == BitChartTimeUnit.Auto) unit = ChooseUnit(min, max); // Choose a step so we don't exceed maxTicks. int step = 1; - var probe = Floor(min, unit); int count = 0; - for (var t = probe; t <= max; t = Next(t, unit, 1)) { count++; if (count > 5000) break; } + for (var t = Floor(min, unit); t <= max; count++) + { + if (count > 5000 || !TryNext(t, unit, 1, out t)) break; + } if (count > maxTicks) step = (int)Math.Ceiling((double)count / maxTicks); var ticks = new List<(double, string)>(); @@ -79,12 +120,12 @@ public static BitChartTimeUnit ChooseUnit(DateTime min, DateTime max) while (cur <= max) { if (cur >= min) - ticks.Add((cur.ToOADate(), (format ?? (d => DefaultFormat(d, unit)))(cur))); - cur = Next(cur, unit, step); + ticks.Add((cur.ToOADate(), (format ?? (d => DefaultFormat(d, unit, culture)))(cur))); if (ticks.Count > maxTicks * 3) break; + if (!TryNext(cur, unit, step, out cur)) break; } if (ticks.Count == 0) - ticks.Add((minOa, (format ?? (d => DefaultFormat(d, unit)))(min))); + ticks.Add((minOa, (format ?? (d => DefaultFormat(d, unit, culture)))(min))); return ticks; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTitleModel.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTitleModel.cs index 57a0debc9f..586d23c29e 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTitleModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/BitChartTitleModel.cs @@ -4,8 +4,9 @@ namespace Bit.BlazorUI; public sealed class BitChartTitleModel { public string Text { get; set; } = ""; - public string Color { get; set; } = "#333"; + public string Color { get; set; } = "var(--bit-clr-fg-pri, #1A1A1A)"; public BitChartPosition Position { get; set; } = BitChartPosition.Top; public BitChartAlign Align { get; set; } = BitChartAlign.Center; public BitChartFont Font { get; set; } = new(); + public BitChartPadding Padding { get; set; } = 10; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotation.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotation.cs index 4ff04424cd..78ed6b7b1d 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotation.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotation.cs @@ -24,8 +24,20 @@ public sealed class BitChartAnnotation public double LineWidth { get; set; } = 2; public List? Dash { get; set; } + /// Number of sides of a (3 = triangle). + public int Sides { get; set; } = 3; + + /// Radius in pixels of a or a + /// . When null a point sizes itself from its line width. + public double? Radius { get; set; } + + /// Rotation in degrees of a . + public double Rotation { get; set; } + public string? Label { get; set; } public string LabelColor { get; set; } = "#fff"; public string LabelBackground { get; set; } = "#ff6384"; + /// Font of the annotation label. + public BitChartFont LabelFont { get; set; } = new() { Size = 11, Weight = "bold" }; public bool DrawBehindDatasets { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotationKind.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotationKind.cs index ce5bdb1843..8d8e5da8a7 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotationKind.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotationKind.cs @@ -1,3 +1,24 @@ namespace Bit.BlazorUI; -public enum BitChartAnnotationKind { Line, Box, Point, Label } +/// The shape an annotation draws, mirroring chartjs-plugin-annotation's annotation types. +public enum BitChartAnnotationKind +{ + /// A horizontal or vertical rule across the plot - a threshold, a target, a marker date. + Line, + + /// A rectangle bounded by XMin/XMax and YMin/YMax - a highlighted region. + Box, + + /// A dot at one coordinate. + Point, + + /// Text in a pill at one coordinate, with no shape of its own. + Label, + + /// An ellipse inscribed in the XMin/XMax and YMin/YMax bounds, for circling a region. + Ellipse, + + /// A regular polygon of sides, centered on the + /// annotation's coordinate with a pixel . + Polygon +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotationPlugin.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotationPlugin.cs index 5b6437593b..8ee416a0bf 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotationPlugin.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartAnnotationPlugin.cs @@ -81,7 +81,71 @@ private void Draw(BitChartPluginContext ctx, BitChartAnnotation a, bool behind) { double x = a.XMin is { } xv ? X(xv, a.XIsIndex) : plot.CenterX; double y = ctx.YForValue(a.Value, a.AxisId); - add(new BitChartSvgCircle { Cx = x, Cy = y, R = a.LineWidth * 2 + 2, Fill = a.FillColor ?? a.Color, Stroke = a.Color, StrokeWidth = a.LineWidth }); + add(new BitChartSvgCircle + { + Cx = x, Cy = y, R = a.Radius ?? a.LineWidth * 2 + 2, + Fill = a.FillColor ?? a.Color, Stroke = a.Color, StrokeWidth = a.LineWidth + }); + if (!string.IsNullOrEmpty(a.Label)) + AddLabel(add, a, x, y - (a.Radius ?? a.LineWidth * 2 + 2) - a.LabelFont.LineHeightPx, "middle"); + break; + } + + case BitChartAnnotationKind.Ellipse: + { + double x1 = a.XMin is { } xm ? X(xm, a.XIsIndex) : plot.Left; + double x2 = a.XMax is { } xM ? X(xM, a.XIsIndex) : plot.Right; + double y1 = a.YMax is { } yM ? ctx.YForValue(yM, a.AxisId) : plot.Top; + double y2 = a.YMin is { } ym ? ctx.YForValue(ym, a.AxisId) : plot.Bottom; + + // Same clamp as the box: bounds outside the visible axis range must not spill past the chart. + x1 = Math.Clamp(x1, plot.Left, plot.Right); + x2 = Math.Clamp(x2, plot.Left, plot.Right); + y1 = Math.Clamp(y1, plot.Top, plot.Bottom); + y2 = Math.Clamp(y2, plot.Top, plot.Bottom); + + double cx = (x1 + x2) / 2, cy = (y1 + y2) / 2; + double rx = Math.Abs(x2 - x1) / 2, ry = Math.Abs(y2 - y1) / 2; + if (rx <= 0 || ry <= 0) break; + + // Two half-turn arcs make a closed ellipse without needing a primitive of its own. + add(new BitChartSvgPath + { + D = $"M {BitChartSvg.N(cx - rx)} {BitChartSvg.N(cy)} " + + $"A {BitChartSvg.N(rx)} {BitChartSvg.N(ry)} 0 1 0 {BitChartSvg.N(cx + rx)} {BitChartSvg.N(cy)} " + + $"A {BitChartSvg.N(rx)} {BitChartSvg.N(ry)} 0 1 0 {BitChartSvg.N(cx - rx)} {BitChartSvg.N(cy)} Z", + Fill = a.FillColor ?? BitChartColorUtil.WithAlpha(a.Color, 0.15), + Stroke = a.Color, StrokeWidth = a.LineWidth, + Dash = BitChartSvg.Dash(a.Dash) + }); + if (!string.IsNullOrEmpty(a.Label)) + AddLabel(add, a, cx, cy, "middle"); + break; + } + + case BitChartAnnotationKind.Polygon: + { + double cx = a.XMin is { } xv ? X(xv, a.XIsIndex) : plot.CenterX; + double cy = ctx.YForValue(a.Value, a.AxisId); + double r = a.Radius ?? 12; + int sides = Math.Max(3, a.Sides); + if (r <= 0) break; + + var poly = new BitChartSvgPolygon + { + Fill = a.FillColor ?? BitChartColorUtil.WithAlpha(a.Color, 0.2), + Stroke = a.Color, StrokeWidth = a.LineWidth + }; + // Starts at the top so a triangle points up, which is what a reader expects of one. + double start = -Math.PI / 2 + a.Rotation * Math.PI / 180; + for (int i = 0; i < sides; i++) + { + double angle = start + 2 * Math.PI * i / sides; + poly.Points.Add((cx + Math.Cos(angle) * r, cy + Math.Sin(angle) * r)); + } + add(poly); + if (!string.IsNullOrEmpty(a.Label)) + AddLabel(add, a, cx, cy - r - a.LabelFont.LineHeightPx, "middle"); break; } @@ -97,8 +161,17 @@ private void Draw(BitChartPluginContext ctx, BitChartAnnotation a, bool behind) private static void AddLabel(Action add, BitChartAnnotation a, double x, double y, string anchor) { - double w = (a.Label!.Length * 7) + 10; - add(new BitChartSvgRect { X = anchor == "end" ? x - w : anchor == "middle" ? x - w / 2 : x, Y = y - 9, Width = w, Height = 18, Rx = 4, Fill = a.LabelBackground }); - add(new BitChartSvgText { X = anchor == "end" ? x - w / 2 : x, Y = y, Text = a.Label!, Fill = a.LabelColor, FontSize = 11, Anchor = "middle", Baseline = "central", FontWeight = "bold" }); + // Measured rather than guessed from the character count, so the pill fits the text at any length. + double fontSize = a.LabelFont.Size; + double w = BitChartTextMeasure.Width(a.Label, fontSize, a.LabelFont.Weight) + 12; + double h = a.LabelFont.LineHeightPx + 6; + double left = anchor == "end" ? x - w : anchor == "middle" ? x - w / 2 : x; + add(new BitChartSvgRect { X = left, Y = y - h / 2, Width = w, Height = h, Rx = 4, Fill = a.LabelBackground }); + add(new BitChartSvgText + { + X = left + w / 2, Y = y, Text = a.Label!, Fill = a.LabelColor, + FontFamily = a.LabelFont.Family, FontSize = fontSize, FontWeight = a.LabelFont.Weight, + Anchor = "middle", Baseline = "central" + }); } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartCenterTextPlugin.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartCenterTextPlugin.cs index 39778eaf40..d799ab167d 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartCenterTextPlugin.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartCenterTextPlugin.cs @@ -13,7 +13,7 @@ public sealed class BitChartCenterTextPlugin : IBitChartPlugin public string Text { get; set; } = ""; /// Optional secondary line shown beneath the main text. public string? Subtext { get; set; } - public string Color { get; set; } = "#333"; + public string Color { get; set; } = "var(--bit-clr-fg-pri, #1A1A1A)"; public string? SubtextColor { get; set; } public BitChartFont Font { get; set; } = new() { Size = 28, Weight = "bold" }; public BitChartFont SubtextFont { get; set; } = new() { Size = 13 }; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartPluginContext.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartPluginContext.cs index 4753decb96..958a7c300e 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartPluginContext.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartPluginContext.cs @@ -20,11 +20,36 @@ public sealed class BitChartPluginContext internal BitChartAxisScale? IndexScale { get; init; } internal Dictionary? ValueScales { get; init; } - internal bool IndexIsCategory { get; init; } - /// Pixel position along the index axis for a category index. - public double XForIndex(int index, bool centered = true) - => IndexScale?.PixelForIndex(index, centered) ?? 0; + /// Datasets the legend has toggled off at runtime. + internal IReadOnlySet? HiddenDatasets { get; init; } + + /// + /// Whether the dataset at the given index is actually drawn. A dataset is hidden either by its own + /// flag or by having been toggled off through the legend, and + /// anything drawn from a dataset's values has to honour both or it outlives the series it describes. + /// + public bool IsDatasetVisible(int datasetIndex) + { + var datasets = Config.Data.Datasets; + if (datasetIndex < 0 || datasetIndex >= datasets.Count) return false; + return !datasets[datasetIndex].Hidden && HiddenDatasets?.Contains(datasetIndex) != true; + } + + /// True when the index axis is a category axis, so indexes - not raw values - place things along it. + public bool IndexIsCategory { get; init; } + + /// + /// Whether categories sit in the middle of their band rather than on its edge. Bars force the + /// centered layout, so anything drawn over the data has to follow the same choice or it lands half + /// a band away from the points it is annotating. + /// + public bool IndexCentered { get; init; } + + /// Pixel position along the index axis for a category index. Follows the chart's own + /// band placement unless the caller overrides it. + public double XForIndex(int index, bool? centered = null) + => IndexScale?.PixelForIndex(index, centered ?? IndexCentered) ?? 0; /// Pixel position along the index axis for a raw value (linear/time axes). public double XForValue(double value) => IndexScale?.PixelFor(value) ?? 0; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendline.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendline.cs new file mode 100644 index 0000000000..ac4c441a30 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendline.cs @@ -0,0 +1,42 @@ +namespace Bit.BlazorUI; + +/// One fitted line drawn over a dataset by . +public sealed class BitChartTrendline +{ + /// Index of the dataset the line is fitted to. + public int DatasetIndex { get; set; } + + /// Which curve is fitted. + public BitChartTrendlineKind Kind { get; set; } = BitChartTrendlineKind.Linear; + + /// Window of the trailing moving average, used by . + public int Period { get; set; } = 5; + + /// Line color. When null it follows the dataset's own border color, dimmed. + public string? Color { get; set; } + + public double LineWidth { get; set; } = 2; + + /// Dash pattern; dashed by default so the fit never reads as another measured series. + public List? Dash { get; set; } = [6, 4]; + + /// + /// Projects a straight fit across the full width of the plot instead of stopping at the first and + /// last data point. Ignored by , which has no + /// meaning outside the data. + /// + public bool Extend { get; set; } + + /// Optional label drawn in a pill at the end of the line. + public string? Label { get; set; } + + public string LabelColor { get; set; } = "#fff"; + + /// Pill color behind the label. When null it follows the line color. + public string? LabelBackground { get; set; } + + public BitChartFont LabelFont { get; set; } = new() { Size = 11, Weight = "bold" }; + + /// Draw the line under the datasets rather than over them. + public bool DrawBehindDatasets { get; set; } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendlineKind.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendlineKind.cs new file mode 100644 index 0000000000..852e08501e --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendlineKind.cs @@ -0,0 +1,15 @@ +namespace Bit.BlazorUI; + +/// The curve a fits through its dataset. +public enum BitChartTrendlineKind +{ + /// Least-squares straight line - the classic "is it going up or down" answer. + Linear, + + /// Trailing simple moving average over points, which + /// smooths a noisy series without straightening it. + MovingAverage, + + /// A flat line at the mean of the series, for reading each point against the average. + Average +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendlinePlugin.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendlinePlugin.cs new file mode 100644 index 0000000000..a87718935a --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Rendering/Plugins/BitChartTrendlinePlugin.cs @@ -0,0 +1,175 @@ +using System.Text; + +namespace Bit.BlazorUI; + +/// +/// Fits a trend line through a cartesian dataset - a least-squares regression, a trailing moving +/// average or the series mean - and draws it over the chart, mirroring what the charting world ships +/// as a trendline plugin. The fit is computed from the same values the chart plots, so a dataset +/// hidden through the legend takes its trend line with it. +/// +public sealed class BitChartTrendlinePlugin : IBitChartPlugin +{ + public string Id => "trendline"; + + public List Trendlines { get; } = new(); + + public BitChartTrendlinePlugin() { } + public BitChartTrendlinePlugin(params BitChartTrendline[] trendlines) => Trendlines.AddRange(trendlines); + + public void BeforeDatasetsDraw(BitChartPluginContext ctx) + { + foreach (var t in Trendlines.Where(t => t.DrawBehindDatasets)) Draw(ctx, t, behind: true); + } + + public void AfterDatasetsDraw(BitChartPluginContext ctx) + { + foreach (var t in Trendlines.Where(t => !t.DrawBehindDatasets)) Draw(ctx, t, behind: false); + } + + private static void Draw(BitChartPluginContext ctx, BitChartTrendline trend, bool behind) + { + if (!ctx.IsCartesian || ctx.Plot is not { } plot) return; + + var datasets = ctx.Config.Data.Datasets; + if (trend.DatasetIndex < 0 || trend.DatasetIndex >= datasets.Count) return; + var ds = datasets[trend.DatasetIndex]; + if (!ctx.IsDatasetVisible(trend.DatasetIndex)) return; + + // (x, y) in data coordinates: an index for a category axis, the point's own x otherwise. + var samples = new List<(double X, double Y)>(); + if (ds.Points is { } points) + { + foreach (var p in points.OrderBy(p => p.X)) samples.Add((p.X, p.Y)); + } + else + { + for (int i = 0; i < ds.Data.Count; i++) + if (ds.Data[i] is { } v) samples.Add((i, v)); + } + if (samples.Count < 2) return; + + bool byIndex = ds.Points is null && ctx.IndexIsCategory; + double Px(double x) => byIndex ? ctx.XForIndex((int)Math.Round(x)) : ctx.XForValue(x); + double Py(double y) => ctx.YForValue(y, ds.YAxisID); + + var fitted = trend.Kind switch + { + BitChartTrendlineKind.MovingAverage => MovingAverage(samples, trend.Period), + BitChartTrendlineKind.Average => Flat(samples), + _ => Regression(samples, trend.Extend, ctx, byIndex, plot) + }; + if (fitted.Count < 2) return; + + string color = trend.Color ?? BitChartColorUtil.WithAlpha( + ds.BorderColor ?? ds.BackgroundColor ?? BitChartColorUtil.Palette(trend.DatasetIndex), 0.85); + + var d = new StringBuilder(); + for (int i = 0; i < fitted.Count; i++) + { + double px = fitted[i].Fixed ? fitted[i].X : Px(fitted[i].X); + double py = Py(fitted[i].Y); + d.Append(i == 0 ? "M " : " L ").Append(BitChartSvg.N(px)).Append(' ').Append(BitChartSvg.N(py)); + } + + Action add = behind ? ctx.AddBehind : ctx.AddFront; + add(new BitChartSvgPath + { + D = d.ToString(), + Fill = "none", + Stroke = color, + StrokeWidth = trend.LineWidth, + Dash = BitChartSvg.Dash(trend.Dash), + LineCap = "round", + LineJoin = "round" + }); + + if (string.IsNullOrEmpty(trend.Label)) return; + + var end = fitted[^1]; + double lx = end.Fixed ? end.X : Px(end.X); + double ly = Py(end.Y); + double w = BitChartTextMeasure.Width(trend.Label, trend.LabelFont.Size, trend.LabelFont.Weight) + 12; + double h = trend.LabelFont.LineHeightPx + 6; + // Pinned inside the plot so a fit that ends at the right edge keeps its pill readable. + double left = Math.Clamp(lx - w, plot.Left, Math.Max(plot.Left, plot.Right - w)); + double top = Math.Clamp(ly - h / 2, plot.Top, Math.Max(plot.Top, plot.Bottom - h)); + + add(new BitChartSvgRect + { + X = left, Y = top, Width = w, Height = h, Rx = 4, + Fill = trend.LabelBackground ?? color + }); + add(new BitChartSvgText + { + X = left + w / 2, Y = top + h / 2, Text = trend.Label!, Fill = trend.LabelColor, + FontFamily = trend.LabelFont.Family, FontSize = trend.LabelFont.Size, FontWeight = trend.LabelFont.Weight, + Anchor = "middle", Baseline = "central" + }); + } + + /// + /// A fitted vertex. Fixed marks a point whose X is already a pixel - the regression uses it + /// to reach the plot edges, which have no data coordinate to convert from. + /// + private readonly record struct Vertex(double X, double Y, bool Fixed = false); + + /// Ordinary least-squares fit, evaluated at the two ends of the run it covers. + private static List Regression(List<(double X, double Y)> samples, bool extend, + BitChartPluginContext ctx, bool byIndex, BitChartArea plot) + { + int n = samples.Count; + double sx = 0, sy = 0, sxy = 0, sxx = 0; + foreach (var (x, y) in samples) { sx += x; sy += y; sxy += x * y; sxx += x * x; } + double denom = n * sxx - sx * sx; + // A vertical run of samples has no least-squares line; the mean is the honest answer for it. + if (Math.Abs(denom) < 1e-12) return Flat(samples); + + double slope = (n * sxy - sx * sy) / denom; + double intercept = (sy - slope * sx) / n; + + double x0 = samples[0].X, x1 = samples[^1].X; + if (!extend) + return [new Vertex(x0, intercept + slope * x0), new Vertex(x1, intercept + slope * x1)]; + + // Extending means walking the line out to the plot edges, so the endpoints are converted the + // other way round: from a pixel back to the data coordinate the fit is expressed in. + double px0 = byIndex ? ctx.XForIndex((int)Math.Round(x0)) : ctx.XForValue(x0); + double px1 = byIndex ? ctx.XForIndex((int)Math.Round(x1)) : ctx.XForValue(x1); + if (Math.Abs(px1 - px0) < 1e-9) + return [new Vertex(x0, intercept + slope * x0), new Vertex(x1, intercept + slope * x1)]; + + double perPixel = (x1 - x0) / (px1 - px0); + double left = px0 < px1 ? plot.Left : plot.Right; + double right = px0 < px1 ? plot.Right : plot.Left; + double dataAtLeft = x0 + (left - px0) * perPixel; + double dataAtRight = x0 + (right - px0) * perPixel; + return + [ + new Vertex(left, intercept + slope * dataAtLeft, Fixed: true), + new Vertex(right, intercept + slope * dataAtRight, Fixed: true) + ]; + } + + /// Trailing simple moving average; the first points average what there is so far. + private static List MovingAverage(List<(double X, double Y)> samples, int period) + { + int p = Math.Max(2, period); + var result = new List(samples.Count); + double sum = 0; + for (int i = 0; i < samples.Count; i++) + { + sum += samples[i].Y; + if (i >= p) sum -= samples[i - p].Y; + result.Add(new Vertex(samples[i].X, sum / Math.Min(i + 1, p))); + } + return result; + } + + /// A flat line at the mean of the series. + private static List Flat(List<(double X, double Y)> samples) + { + double mean = samples.Average(s => s.Y); + return [new Vertex(samples[0].X, mean), new Vertex(samples[^1].X, mean)]; + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor index 8478c07ac1..53b1668b51 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor @@ -7,13 +7,18 @@ @Columns -
"auto", _ => "ltr" })"> +@* The two grid-owned Ctrl/⌘ shortcuts are conditional, so the capture-phase key guard that cancels + their browser defaults (see BitDataGrid.ts) reads whether they are live off the root rather than + guessing: a grid without them must leave Ctrl+A and Ctrl+C to the browser. *@ +
"auto", _ => "ltr" })" + data-bit-dtg-copy="@(ClipboardCopy ? "true" : null)" + data-bit-dtg-select-all="@(SelectionMode == BitDataGridSelectionMode.Multiple ? "true" : null)"> @* Announces sort/filter/page changes to screen readers; these are otherwise silent view mutations. *@
@_srAnnouncement
@* ---------------------------------------------------------- Toolbar *@ - @if (ShowToolbar || ToolbarTemplate is not null || ShowColumnChooser || ShowCsvExport || ShowExcelExport || (Editable && NewItemFactory is not null)) + @if (ShowToolbar || ToolbarTemplate is not null || ShowColumnChooser || ShowCsvExport || ShowExcelExport || SearchActive || (Editable && NewItemFactory is not null)) {
@@ -22,6 +27,29 @@ { } + @if (SearchActive) + { + @* type="search" gives the browser's own clear affordance and the right virtual + keyboard; the explicit clear button covers the browsers that render neither. *@ + + }
@if (_filters.Count > 0) @@ -30,11 +58,11 @@ } @if (ShowCsvExport) { - + } @if (ShowExcelExport) { - + } @if (ShowColumnChooser) { @@ -51,12 +79,18 @@ @if (_showColumnChooserPanel) { -
+ @* Escape closes the panel from anywhere inside it, the dismissal every popup owes its keyboard + users; the toggle button keeps aria-expanded in sync either way. *@ +
@foreach (var col in AllColumns) { + @* The last visible column can't be hidden - a grid with no columns would be an empty + shell - so its checkbox is disabled rather than silently refusing the click. *@ } @@ -70,7 +104,19 @@ @* ------------------------------------------------------- Grid viewport *@
-
+ @* aria-multiselectable tells assistive tech that rows carry a meaningful aria-selected state + (only true for Multiple - Single selection is the default single-select behavior), and + aria-busy marks the grid as still updating while a load is in flight. *@ + @* A hierarchical grid is a treegrid, not a grid: that is what tells assistive tech the rows + nest, and what makes the per-row aria-level/aria-expanded meaningful. *@ + @* A grid needs an accessible name for assistive tech to announce it (and to tell several grids + on one page apart); AriaLabel names this one, falling back to the generic localized default. *@ +
@if (ShowHeader) { @@ -78,6 +124,10 @@ @if (HasColumnGroups) {
+ @if (HasRowNumberColumn) + { +
+ } @if (HasReorderColumn) {
@@ -105,6 +155,16 @@ }
@{ var headerColIndex = 0; } + @if (HasRowNumberColumn) + { + headerColIndex++; + @* The "#" glyph reads as nothing useful to a screen reader, so the cell + carries a real name and hides the glyph from the accessibility tree. *@ +
+ +
+ } @if (HasReorderColumn) { headerColIndex++; @@ -167,18 +227,22 @@ } ; } + @* The header label ellipsises in a narrow column, so it carries its full + text as a native tooltip - except when a HeaderTemplate owns the markup + (and any tooltip it wants) itself. *@ @if (ColumnSortable(column)) { @* A real button gives native keyboard activation (Enter/Space) and an implicit button role, so no custom keydown handling is needed and Space won't scroll the page. *@ - } else { - + @headerInner } @@ -197,9 +261,14 @@ @if (ColumnResizable(column)) { - + @onpointerdown:stopPropagation="true" + @ondblclick="() => AutoFitAsync(column)" + @ondblclick:stopPropagation="true"> }
} @@ -214,6 +283,10 @@ { @* The filter row is always the last header row, so its aria-rowindex is HeaderRowCount. *@
+ @if (HasRowNumberColumn) + { +
+ } @if (HasReorderColumn) {
@@ -262,13 +335,23 @@ @if (Loading) {
-
@Strings.LoadingText
+
+ @if (LoadingTemplate is not null) + { + @LoadingTemplate + } + else + { + + @Strings.LoadingText + } +
} else if (TotalCount == 0 && PendingNewItem is null && !IsInfiniteMode && !UseServerVirtualization) {
-
+
@if (EmptyTemplate is not null) { @EmptyTemplate @@ -289,7 +372,7 @@ @if (InfiniteItems.Count == 0 && !InfiniteLoading) {
-
+
@if (EmptyTemplate is not null) { @EmptyTemplate @@ -324,7 +407,7 @@ {
-
+
@@ -332,7 +415,7 @@ else if (!InfiniteHasMore) {
-
+
@Strings.EndOfResultsText
@@ -347,7 +430,7 @@ @if (_serverVirtualizeEmpty) {
-
+
@if (EmptyTemplate is not null) { @EmptyTemplate @@ -366,7 +449,7 @@
-
+
@@ -392,6 +475,10 @@ {
internal static class BitDataGridExcelWriter { @@ -54,8 +55,28 @@ internal static class BitDataGridExcelWriter """; - // Minimal style sheet: style 0 is the default cell, style 1 the bold header. The two fills and - // the empty border are mandatory filler (SpreadsheetML requires fill 0 = none and fill 1 = gray125). + // The cell-format (cellXfs) contract shared by both style sheets, so the sheet writer can pick a + // format without knowing whether the export is styled: + // 0 data | 1 header | 2 striped data | 3 data+date | 4 striped+date | 5 data+datetime | 6 striped+datetime + // An unstyled export has no stripe fill, so its striped entries are identical to their plain + // counterparts - the indices stay the same either way. + private const int StyleData = 0; + private const int StyleHeader = 1; + private const int StyleStripe = 2; + private const int StyleDate = 3; + private const int StyleStripeDate = 4; + private const int StyleDateTime = 5; + private const int StyleStripeDateTime = 6; + + // Built-in SpreadsheetML number formats, so no block is needed: 14 is the locale's short + // date, 22 its short date + time. Using the built-ins means the workbook renders dates the way the + // opening machine expects rather than pinning one culture's pattern into the file. + private const int DateNumFmtId = 14; + private const int DateTimeNumFmtId = 22; + + // Minimal style sheet: style 0 is the default cell, style 1 the bold header, and 3/5 the two date + // formats (2/4/6 mirror them, since an unstyled export has no stripe fill). The two fills and the + // empty border are mandatory filler (SpreadsheetML requires fill 0 = none and fill 1 = gray125). private const string StylesXml = """ @@ -64,7 +85,7 @@ internal static class BitDataGridExcelWriter - + """; @@ -105,9 +126,8 @@ public static byte[] Write( return stream.ToArray(); } - /// Builds the style sheet for a styled export. The cell-format (cellXfs) contract with - /// the sheet writer: index 0 = data row (the implicit default for cells with no s - /// attribute), 1 = header, 2 = alternating (striped) data row. + /// Builds the style sheet for a styled export, following the same cellXfs contract the + /// unstyled declares (see the Style* constants). private static string BuildStylesXml(BitDataGridExcelStyle style) { // "#rrggbb" (CSS) -> "FFRRGGBB" (SpreadsheetML ARGB); anything else falls back to default. @@ -164,16 +184,21 @@ int AddFill(string? argb) sb.Append(""); - void AppendXf(int fontId, int fillId) - => sb.Append($" sb.Append($" 0 ? " applyFill=\"1\"" : "") .Append(borderId > 0 ? " applyBorder=\"1\"" : "") + .Append(numFmtId > 0 ? " applyNumberFormat=\"1\"" : "") .Append("/>"); - sb.Append(""); - AppendXf(0, rowFill); // 0: data row (implicit default) - AppendXf(1, headerFill); // 1: header - AppendXf(0, stripeFill); // 2: striped data row + sb.Append(""); + AppendXf(0, rowFill); // 0: data row (implicit default) + AppendXf(1, headerFill); // 1: header + AppendXf(0, stripeFill); // 2: striped data row + AppendXf(0, rowFill, DateNumFmtId); // 3: date + AppendXf(0, stripeFill, DateNumFmtId); // 4: striped date + AppendXf(0, rowFill, DateTimeNumFmtId); // 5: date + time + AppendXf(0, stripeFill, DateTimeNumFmtId); // 6: striped date + time sb.Append(""); sb.Append(""); @@ -207,7 +232,7 @@ private static void WriteSheet( writer.Write(""); foreach (var column in columns) { - WriteInlineString(writer, column.DisplayTitle, styleIndex: 1); + WriteInlineString(writer, column.DisplayTitle, StyleHeader); } writer.Write(""); @@ -221,11 +246,12 @@ private static void WriteSheet( // Cell format 0 (the implicit default) is the data-row style; in a styled export the // alternating rows use format 2 (the stripe fill), matching the grid's nth-child(even) // striping (sheet data row 2 = data index 1). - var cellStyle = styled && rowIndex % 2 == 1 ? 2 : 0; + var stripe = styled && rowIndex % 2 == 1; + var cellStyle = stripe ? StyleStripe : StyleData; writer.Write(""); for (var colIndex = 0; colIndex < columns.Count; colIndex++) { - WriteCell(writer, columns[colIndex], item, cellStyle); + WriteCell(writer, columns[colIndex], item, cellStyle, stripe); // Mirror the rendered layout: a spanning cell covers its following neighbours, whose // own values/spans are skipped (a merged region keeps only its top-left cell's value). @@ -246,6 +272,14 @@ private static void WriteSheet( writer.Write(""); + // Turn the header row into Excel's own filter row, so the exported sheet opens with the same + // per-column sort/filter affordances the grid has. The schema puts autoFilter after sheetData + // and before mergeCells, so the order here is not interchangeable. + if (columns.Count > 0) + { + writer.Write($""); + } + if (merges is not null) { writer.Write($""); @@ -297,10 +331,34 @@ private static string CellRef(int columnIndex, int row) return letters + row.ToString(CultureInfo.InvariantCulture); } - private static void WriteCell(TextWriter writer, BitDataGridColumn column, TItem item, int styleIndex) + private static void WriteCell(TextWriter writer, BitDataGridColumn column, TItem item, int styleIndex, bool stripe) { var s = styleIndex > 0 ? $" s=\"{styleIndex}\"" : ""; - var value = column.GetValue(item); + // GetExportValue resolves the column's ExportValue selector when one is set (which is what + // gives a template-only column a real exported value), and the bound field's value otherwise. + var value = column.GetExportValue(item); + + // Dates go in as real date cells (a serial number under a date format) rather than text, so + // the sheet can sort, filter and compute on them; the display text is only the fallback for a + // value Excel's serial calendar cannot represent (see TryDateSerial). + if (value is DateOnly or DateTime or DateTimeOffset) + { + if (TryDateSerial(value, out var serial, out var hasTime)) + { + var dateStyle = hasTime + ? (stripe ? StyleStripeDateTime : StyleDateTime) + : (stripe ? StyleStripeDate : StyleDate); + writer.Write($""); + writer.Write(serial.ToString("0.##########", CultureInfo.InvariantCulture)); + writer.Write(""); + } + else + { + WriteInlineString(writer, column.GetFormattedExportValue(item), styleIndex); + } + return; + } + switch (value) { case null: @@ -316,7 +374,7 @@ private static void WriteCell(TextWriter writer, BitDataGridColumn // string instead of a numeric cell. case float f when !float.IsFinite(f): case double d when !double.IsFinite(d): - WriteInlineString(writer, column.GetFormattedValue(item), styleIndex); + WriteInlineString(writer, column.GetFormattedExportValue(item), styleIndex); break; // Native numeric cells keep their real value so spreadsheet math works on the export; // a column Format (e.g. "C2") is presentation-only and intentionally not applied here. @@ -326,11 +384,41 @@ private static void WriteCell(TextWriter writer, BitDataGridColumn writer.Write(""); break; default: - WriteInlineString(writer, column.GetFormattedValue(item), styleIndex); + WriteInlineString(writer, column.GetFormattedExportValue(item), styleIndex); break; } } + /// + /// Converts a date/time value to the serial number Excel stores dates as (days since 1899-12-30, + /// the fraction being the time of day), and reports whether it carries a time worth showing. + /// + /// Returns false - so the caller writes the display text instead - for anything before + /// 1900-03-01. Excel's serial calendar contains a deliberate 1900 leap-year bug that OADate does + /// not reproduce, so every earlier date would land one day off in the workbook. + /// + /// A is written as its own wall-clock time (the offset itself has no + /// representation in a date cell), matching the text an unconverted export would have carried. + /// + private static bool TryDateSerial(object value, out double serial, out bool hasTime) + { + var moment = value switch + { + DateOnly d => d.ToDateTime(TimeOnly.MinValue), + DateTime dt => dt, + DateTimeOffset dto => dto.DateTime, + _ => default + }; + + hasTime = moment.TimeOfDay != TimeSpan.Zero; + serial = 0; + // 61 is 1900-03-01, the first serial Excel and OADate agree on. + if (moment < new DateTime(1900, 3, 1)) return false; + + serial = moment.ToOADate(); + return true; + } + private static void WriteInlineString(TextWriter writer, string text, int styleIndex = 0) { writer.Write(styleIndex > 0 diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Infrastructure/BitDataGridQueryableProcessor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Infrastructure/BitDataGridQueryableProcessor.cs index fb951d9853..cbd5cae627 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Infrastructure/BitDataGridQueryableProcessor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Infrastructure/BitDataGridQueryableProcessor.cs @@ -19,6 +19,81 @@ public static IQueryable Apply( IReadOnlyDictionary> columns) => ApplySorts(ApplyFilters(source, filters, columns), sorts, columns); + /// Applies the quick-search term, then the filters and sorts, onto the queryable. + public static IQueryable Apply( + IQueryable source, + string? search, + IReadOnlyList filters, + IReadOnlyList sorts, + IReadOnlyDictionary> columns) + => ApplySorts(ApplyFilters(ApplySearch(source, search, columns.Values), filters, columns), sorts, columns); + + /// + /// Translates the grid-wide quick search into a single OR of case-insensitive Contains + /// predicates over the searchable string columns, so the provider runs it at the source + /// (e.g. one SQL WHERE … LIKE … OR … LIKE …). Non-string columns are skipped: their text is + /// produced by .NET formatting the provider cannot reproduce, so matching them would need the rows + /// in memory; when a searchable column exists but none of them translate, the search is left off + /// rather than silently emptying the grid. With no searchable column at all there is + /// nothing a term could ever match, so it matches no row - the same contract as + /// over an in-memory source. + /// + public static IQueryable ApplySearch( + IQueryable source, + string? search, + IEnumerable> columns) + { + if (string.IsNullOrWhiteSpace(search)) return source; + + var term = search.Trim().ToLower(); + var toLower = typeof(string).GetMethod(nameof(string.ToLower), Type.EmptyTypes)!; + var contains = typeof(string).GetMethod(nameof(string.Contains), new[] { typeof(string) })!; + + var anySearchable = false; + ParameterExpression? param = null; + Expression? body = null; + foreach (var column in columns) + { + if (!column.IsSearchable) continue; + anySearchable = true; + if (column.Accessor is null) continue; + var lambda = column.Accessor.PropertyLambda; + if (lambda.Body.Type != typeof(string)) continue; + + // Every column accessor builds its lambda over its own parameter instance, so rebind the + // member expressions onto one shared parameter before OR-ing them into a single predicate. + param ??= lambda.Parameters[0]; + var member = ReplaceParameter(lambda.Body, lambda.Parameters[0], param); + + var match = Expression.AndAlso( + Expression.NotEqual(member, Expression.Constant(null, typeof(string))), + Expression.Call(Expression.Call(member, toLower), contains, Expression.Constant(term))); + body = body is null ? match : Expression.OrElse(body, match); + } + + if (body is null || param is null) + { + // No searchable column at all: nothing to match against, so the term excludes every row + // (what the in-memory pipeline does). Some searchable columns exist but none translate: + // leave the search off rather than emptying a grid the provider simply cannot filter. + return anySearchable ? source : source.Where(_ => false); + } + + return source.Where(Expression.Lambda>(body, param)); + } + + private static Expression ReplaceParameter(Expression body, ParameterExpression from, ParameterExpression to) + => ReferenceEquals(from, to) ? body : new ParameterRebinder(from, to).Visit(body); + + private sealed class ParameterRebinder : ExpressionVisitor + { + private readonly ParameterExpression _from; + private readonly ParameterExpression _to; + public ParameterRebinder(ParameterExpression from, ParameterExpression to) { _from = from; _to = to; } + protected override Expression VisitParameter(ParameterExpression node) + => ReferenceEquals(node, _from) ? _to : base.VisitParameter(node); + } + public static IQueryable ApplyFilters( IQueryable source, IReadOnlyList filters, diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridReadRequest.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridReadRequest.cs index 51712093ad..d143e23f2f 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridReadRequest.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridReadRequest.cs @@ -24,5 +24,13 @@ public sealed class BitDataGridReadRequest /// public IReadOnlyList Groups { get; init; } = Array.Empty(); + /// + /// The grid-wide quick-search term (the grid's search box, or its SearchText parameter), or + /// null when no search is active. It is a free-text term the handler should match across the + /// columns it considers searchable, in addition to - not instead of - the per-column + /// . + /// + public string? Search { get; init; } + public CancellationToken CancellationToken { get; init; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridState.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridState.cs index 4795ce3bfa..4efc7b08a9 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridState.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridState.cs @@ -21,12 +21,31 @@ public sealed class BitDataGridState /// The user-selected page size, or null when the grid's PageSize parameter applies. public int? PageSize { get; set; } + /// The grid-wide quick-search term, or null when no search was active. + public string? Search { get; set; } + public List Sorts { get; set; } = new(); public List Filters { get; set; } = new(); public List Groups { get; set; } = new(); + /// + /// Whether groups were collapsed by default when the snapshot was taken (the state + /// GroupsInitiallyCollapsed sets and ExpandAllGroupsAsync/CollapseAllGroupsAsync + /// flip). Only meaningful together with . + /// + public bool GroupsCollapsed { get; set; } + + /// + /// The groups whose expanded state differs from , as the stable paths + /// the grid identifies them by. Restoring both fields brings back exactly which groups were open, + /// so a persisted view opens the way the user left it. + /// Tree-node expansion is deliberately not captured: a tree node is identified by whatever + /// KeyField returns, which is not guaranteed to be serializable. + /// + public List GroupExpansionOverrides { get; set; } = new(); + /// Per-column layout state (visibility, resized width, display order). public List Columns { get; set; } = new(); } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridStrings.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridStrings.cs index 587d0697cc..d8abf1270e 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridStrings.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Models/BitDataGridStrings.cs @@ -8,6 +8,13 @@ namespace Bit.BlazorUI; /// public class BitDataGridStrings { + /// + /// Default accessible name of the grid itself (its role="grid" element), used when no + /// AriaLabel is given. A page with several grids should name each one through + /// AriaLabel instead, so screen-reader users can tell them apart. + /// + public string GridLabel { get; set; } = "Data grid"; + /// Shown when the grid has no rows to display. public string EmptyText { get; set; } = "No records to display."; @@ -17,6 +24,12 @@ public class BitDataGridStrings /// Header of the command (Edit/Delete) column. public string ActionsText { get; set; } = "Actions"; + /// Visible header glyph of the row-number column. + public string RowNumberHeader { get; set; } = "#"; + + /// Accessible name of the row-number column's header (the "#" glyph reads as nothing). + public string RowNumberLabel { get; set; } = "Row number"; + /// Toolbar button that begins adding a new row. public string AddRowText { get; set; } = "+ Add"; @@ -32,6 +45,21 @@ public class BitDataGridStrings /// Toolbar button that opens the column chooser. public string ColumnsText { get; set; } = "Columns"; + /// Accessible label of the column-chooser panel. + public string ColumnChooserLabel { get; set; } = "Choose columns"; + + /// Placeholder of the toolbar's quick-search box. + public string SearchPlaceholder { get; set; } = "Search…"; + + /// Accessible label of the toolbar's quick-search box. + public string SearchLabel { get; set; } = "Search all columns"; + + /// Accessible label of the button that clears the quick search. + public string ClearSearchLabel { get; set; } = "Clear search"; + + /// Tooltip of a resizable column's drag handle. + public string ResizeColumnTitle { get; set; } = "Drag to resize, or double-click to fit the content"; + public string EditText { get; set; } = "Edit"; public string DeleteText { get; set; } = "Delete"; public string SaveText { get; set; } = "Save"; @@ -69,6 +97,8 @@ public class BitDataGridStrings public string FilterOpGreaterThanOrEqual { get; set; } = "≥"; public string FilterOpLessThan { get; set; } = "<"; public string FilterOpLessThanOrEqual { get; set; } = "≤"; + public string FilterOpIsEmpty { get; set; } = "Is blank"; + public string FilterOpIsNotEmpty { get; set; } = "Is not blank"; public string BooleanTrueText { get; set; } = "True"; public string BooleanFalseText { get; set; } = "False"; @@ -127,10 +157,30 @@ public class BitDataGridStrings public string AnnouncementSortCleared { get; set; } = "Sorting by {0} removed"; public string AnnouncementFiltered { get; set; } = "Filter applied on {0}"; public string AnnouncementFilterCleared { get; set; } = "Filter on {0} cleared"; + /// Announced when every column filter is cleared at once (the toolbar's Clear filters + /// button, or ClearFiltersAsync). + public string AnnouncementFiltersCleared { get; set; } = "All filters cleared"; + /// Announced when every sort is removed at once (ClearSortsAsync). + public string AnnouncementSortsCleared { get; set; } = "Sorting cleared"; + /// Announced when every grouping is removed at once (ClearGroupsAsync). + public string AnnouncementGroupsCleared { get; set; } = "Grouping cleared"; + /// Announced after a bulk selection change. {0} = the number of selected rows. + public string AnnouncementRowsSelected { get; set; } = "{0} rows selected"; + /// Announced when the selection is cleared. + public string AnnouncementSelectionCleared { get; set; } = "Selection cleared"; /// {0} = current page, {1} = total pages. public string AnnouncementPage { get; set; } = "Page {0} of {1}"; /// Announced after a row is deleted (via the Delete button or the Delete key). public string AnnouncementRowDeleted { get; set; } = "Row deleted"; + /// {0} = the search term. + public string AnnouncementSearched { get; set; } = "Searching for {0}"; + public string AnnouncementSearchCleared { get; set; } = "Search cleared"; + /// {0} = column title. + public string AnnouncementGrouped { get; set; } = "Grouped by {0}"; + /// {0} = column title. + public string AnnouncementUngrouped { get; set; } = "Grouping by {0} removed"; + /// Announced after a clipboard copy. {0} = the number of rows copied. + public string AnnouncementRowsCopied { get; set; } = "{0} rows copied to the clipboard"; /// Footer aggregate labels. {0} = the formatted aggregate value. public string AggregateSumFormat { get; set; } = "Σ {0}"; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ErrorBoundary/BitErrorBoundary.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ErrorBoundary/BitErrorBoundary.razor index f639b86d93..76ac0661fa 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ErrorBoundary/BitErrorBoundary.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ErrorBoundary/BitErrorBoundary.razor @@ -3,7 +3,25 @@ @if (CurrentException is null) { - @(Body ?? ChildContent) + @* The boundary cascades itself so that anything inside it can hand it an exception the renderer + never saw - the Blazor counterpart of react-error-boundary's useErrorBoundary/showBoundary. + Fixed, because the value is the component instance and never changes. *@ + + @(Body ?? ChildContent) + + + @* What Capture left behind, thrown from a child so that the renderer routes it back here as it + routes anything else the content throws. See _BitErrorBoundaryThrower. *@ + var captured = TakeCapturedException(); + + if (captured is not null) + { + @RenderThrower(captured) + } +} +else if (ErrorTemplate is not null) +{ + @ErrorTemplate(_Context) } else if (ErrorContent is not null) { @@ -11,38 +29,130 @@ else if (ErrorContent is not null) } else { -
- - - - + @* An assertive live region with the alert role, so the error is read out where it appeared rather + than only seen: the content it replaced is gone and nothing else on the page says so. + An attribute written after the splat wins over the one the page passed in through HtmlAttributes, + so every attribute below reads what came in with them and resolves against it rather than writing + its own value over it - a null written after the splat does not leave the splatted attribute alone, + it removes it. Markup rarely reaches HtmlAttributes with an id, a dir, a class or a style, since + parameters are matched by name without regard to case and those four land on Id, Dir, Class and + Style instead; a dictionary handed to HtmlAttributes as a whole carries them all the same, which + is what the fallbacks here and the merges in _RootClass / _RootStyle are for. *@ +
+ @if (HideIcon is false) + { + if (IconTemplate is not null) + { + @IconTemplate + } + else if (_Icon is not null) + { +
@TableCaption
SeriesXY
@(ds.Label ?? "Series")@p.X.ToString(System.Globalization.CultureInfo.InvariantCulture)@p.Y.ToString(System.Globalization.CultureInfo.InvariantCulture)@Fmt(p.X)@Fmt(p.Y)
Series@label@(ci < data.Labels.Count ? data.Labels[ci] : "")
@(ds.Label ?? "Series")@(r is { } rr ? $"{rr.Low}–{rr.High}" : "")@(ci < ranges.Count && ranges[ci] is { } rr ? $"{Fmt(rr.Low)}–{Fmt(rr.High)}" : "")@(v?.ToString(System.Globalization.CultureInfo.InvariantCulture) ?? "")@CellText(ds, ci)
-