diff --git a/.github/workflows/_.yaml b/.github/workflows/_.yaml new file mode 100644 index 0000000..709cb70 --- /dev/null +++ b/.github/workflows/_.yaml @@ -0,0 +1,58 @@ +name: CI/CD +env: { DOTNET_NOLOGO: true } +on: + workflow_call: + inputs: + publish: { type: boolean, default: false, description: Publish application } + environment: { type: string, default: dev, description: Choose publish environment } +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: 'true' + + - name: Read .NET Version + shell: pwsh + id: dotnet-version + run: | + $version = (Get-Content .\global.json -Raw | ConvertFrom-Json).sdk.version.TrimEnd('0') + 'x' + "version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: { dotnet-version: "${{ steps.dotnet-version.outputs.version }}" } + + - name: Setup tools + run: | + dotnet workload install wasm-tools + npm install -g tailwindcss + + - name: Restore + working-directory: src/TabKeeper.UI.Wasm + run: | + npm install + dotnet restore + + - name: Build + working-directory: src/TabKeeper.UI.Wasm + run: dotnet build -c Release --no-restore + + - name: Publish + if: ${{ inputs.publish }} + working-directory: src/TabKeeper.UI.Wasm + shell: pwsh + run: | + .\css.ps1 -publish + dotnet publish --no-restore --no-build + + - name: Publish to Cloudflare Pages + if: ${{ inputs.publish }} + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy artifacts/src/publish/TabKeeper.UI.Wasm/release/wwwroot --project-name=tab-keeper --branch ${{ inputs.environment }} diff --git a/.github/workflows/_ci.yaml b/.github/workflows/_ci.yaml deleted file mode 100644 index a649543..0000000 --- a/.github/workflows/_ci.yaml +++ /dev/null @@ -1,65 +0,0 @@ -name: Release Workflow - -env: - DOTNET_NOLOGO: true - -on: - workflow_call: - inputs: - publish: - description: Publish to nuget or not - default: false - type: boolean - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: 'true' - - - name: Setup .NET - uses: actions/setup-dotnet@v4.0.0 - with: { dotnet-version: 8.0.x } - - - name: Setup wasm-tools - run: dotnet workload install wasm-tools - - - name: Setup tailwindcss - run: npm install -g tailwindcss - - - name: Setup Nerdbank.GitVersioning - uses: dotnet/nbgv@v0.4.2 - id: nbgv - with: { setAllVars: true } - - - name: Restore - working-directory: src/TabKeeper.UI.Wasm - run: | - npm install - dotnet restore - - - name: Build - working-directory: src/TabKeeper.UI.Wasm - run: dotnet build --no-restore - - - name: Publish - if: ${{ inputs.publish }} - working-directory: src/TabKeeper.UI.Wasm - shell: pwsh - run: | - .\css.ps1 -publish - dotnet publish --no-restore --no-build - - - name: Push to Cloudflare Pages - if: ${{ inputs.publish }} - uses: cloudflare/pages-action@v1 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - projectName: tab-keeper - directory: artifacts/src/publish/TabKeeper.UI.Wasm/release/wwwroot - wranglerVersion: '3' \ No newline at end of file diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 58910bb..58f6aea 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,17 +1,16 @@ -name: Build - -env: - DOTNET_NOLOGO: true - +name: build +env: { DOTNET_NOLOGO: true } on: - workflow_dispatch: pull_request: - branches: [main, dev] + branches: + - main paths: - - "version.json" - - "src/**/*.cs" - - "src/**/*.csproj" - + - src/** + - test/** + types: + - opened + - ready_for_review + - review_requested jobs: - Build: - uses: panoukos41/TabKeeper/.github/workflows/_ci.yaml@dev \ No newline at end of file + pipeline: + uses: panoukos41/TabKeeper/.github/workflows/_.yaml@main diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index b1fe5ea..45a1555 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,20 +1,29 @@ -name: Publish - -env: - DOTNET_NOLOGO: true - +name: publish +env: { DOTNET_NOLOGO: true } on: workflow_dispatch: push: - branches: [main, dev] + branches: + - main + tags: + - v[0-9]+.[0-9]+.[0-9]+ # Only matches vX.X.X where X is a number paths: - - "version.json" - - "src/**/*.cs" - - "src/**/*.csproj" - + - src/** + - test/** jobs: - Build: - uses: panoukos41/TabKeeper/.github/workflows/_ci.yaml@dev - with: - publish: true - secrets: inherit \ No newline at end of file + pipeline: + runs-on: ubuntu-latest + steps: + - name: Determine if prod + if: startsWith(github.ref, 'refs/tags/v') + run: echo "environment=main" >> $GITHUB_ENV + + - name: Determine if dev + if: startsWith(github.ref, 'refs/heads/main') + run: echo "environment=dev" >> $GITHUB_ENV + + - name: Publish + uses: panoukos41/TabKeeper/.github/workflows/_.yaml@main + with: + publish: true + environment: $environment diff --git a/Directory.Build.props b/Directory.Build.props index ddb467f..1f8db99 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,36 +1,31 @@ - + preview enable true true Debug - $(NoWarn);CS8509;IDE0039;IDE0130;IDE0290;IDE0060;RZ10012 + True + $(NoWarn);CS8509;IDE0039;IDE0130;IDE0290;IDE0060;RZ10012;IDE0052;BL0007;CA1816 + $(WarningsAsErrors);RZ2012; - $(MSBuildThisFileDirectory)artifacts/default - $(MSBuildThisFileDirectory)artifacts/tests - $(MSBuildThisFileDirectory)artifacts/tools - $(MSBuildThisFileDirectory)artifacts/samples - $(MSBuildThisFileDirectory)artifacts/src + $([System.IO.Path]::Combine( + $(MSBuildThisFileDirectory), + "artifacts", + $([MSBuild]::MakeRelative($(MSBuildThisFileDirectory),$(MSBuildProjectDirectory)).Replace("$(MSBuildProjectName)", '').TrimEnd('/')) + )) true + true + false Panagiotis Athanasiou - panoukos41 - Copyright (c) 2023 $(Authors) - + Copyright (c) $([System.DateTimeOffset]::UtcNow.ToString("yyyy")) $(Authors) + https://www.github.com/panoukos41/TabKeeper git - MIT - - - - - - - diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..22b390d --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,41 @@ + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GitVersion.yaml b/GitVersion.yaml new file mode 100644 index 0000000..6e3b19e --- /dev/null +++ b/GitVersion.yaml @@ -0,0 +1,8 @@ +workflow: GitHubFlow/v1 +branches: + main: + label: beta + increment: Patch + feature: + label: alpha + increment: Minor diff --git a/TabKeeper.sln b/TabKeeper.sln index 955f9f4..d04a31b 100644 --- a/TabKeeper.sln +++ b/TabKeeper.sln @@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{689C1AA2-E .gitignore = .gitignore .gitmodules = .gitmodules Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props global.json = global.json LICENSE = LICENSE publish.ps1 = publish.ps1 @@ -94,4 +95,3 @@ Global SolutionGuid = {26EECD34-43C6-4F7A-A567-0F8AC7F82094} EndGlobalSection EndGlobal -bal diff --git a/TabKeeper.slnx b/TabKeeper.slnx index fb40539..eb06f1e 100644 --- a/TabKeeper.slnx +++ b/TabKeeper.slnx @@ -1,35 +1,16 @@ - - - - - - - - - - - - + + + + - - - - - - - - - - - + + + + -th="Directory.Build.props" /> - - - - - + + - \ No newline at end of file + diff --git a/global.json b/global.json index 2ddda36..93681ff 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.0", + "version": "9.0.0", "rollForward": "latestMinor", "allowPrerelease": false } diff --git a/src-modules/Core b/src-modules/Core index 68a3c27..ac13f6b 160000 --- a/src-modules/Core +++ b/src-modules/Core @@ -1 +1 @@ -Subproject commit 68a3c27d33bc48a1e7550c94a666f8e148d645fa +Subproject commit ac13f6b45cf53021dd55a57c28295e3b280d04b4 diff --git a/src/TabKeeper.UI.Wasm/App.razor b/src/TabKeeper.UI.Wasm/App.razor index 28bf6a5..c4a6d08 100644 --- a/src/TabKeeper.UI.Wasm/App.razor +++ b/src/TabKeeper.UI.Wasm/App.razor @@ -1,14 +1,16 @@ -@using TabKeeper.Layout +@using System.Runtime.InteropServices.JavaScript +@using TabKeeper.Layout + +@inject TranslateService translate - - Not found + @("general.not-found.title" | translate) -

Sorry, there's nothing at this address.

+

@("general.not-found.description" | translate)

diff --git a/src/TabKeeper.UI.Wasm/Common/IndexedDB/IndexedDdJs.cs b/src/TabKeeper.UI.Wasm/Common/IndexedDB/IndexedDdJs.cs new file mode 100644 index 0000000..a982cad --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Common/IndexedDB/IndexedDdJs.cs @@ -0,0 +1,316 @@ +using Microsoft.JSInterop; +using System.Collections.Concurrent; +using System.Text.Json; + +namespace TabKeeper.Common.IndexedDB; + +/// +/// A database definition describing the database schema. +/// +public sealed record IDBDatabaseDefinition +{ + /// + /// The database name. + /// + public required string Name { get; init; } + + /// + /// The database version. + /// + public int Version { get; set; } + + /// + /// The database store definitions. + /// + public required IDBObjectStoreDefinition[] ObjectStores { get; init; } +} + +/// +/// A store index definition describing the index. +/// +public sealed record IDBIndexDefinition +{ + /// + /// The index name. + /// + public required string Name { get; init; } + + /// + /// The index key path. + /// + public required string KeyPath { get; init; } + + /// + /// + /// + public bool MultiEntry { get; init; } + + /// + /// + /// + public bool Unique { get; init; } +} + +/// +/// A store definition describing the store. +/// +public class IDBObjectStoreDefinition +{ + /// + /// + /// + public required string Name { get; init; } + + /// + /// + /// + public string? KeyPath { get; init; } + + /// + /// + /// + public bool AutoIncrement { get; init; } + + /// + /// + /// + public IDBIndexDefinition[] Indexes { get; init; } = []; +} + +public abstract class IDBBase +{ + public IJSRuntime JSRuntime { get; } + + public IJSObjectReference JSReference { get; } + + protected IDBBase(IJSRuntime jSRuntime, IJSObjectReference jsReference) + { + JSRuntime = jSRuntime; + JSReference = jsReference; + } + + public virtual ValueTask DisposeAsync() + { + GC.SuppressFinalize(this); + return JSReference.DisposeAsync(); + } +} + +public class IDBFactory +{ + private static IJSObjectReference? module = null; + private readonly IJSRuntime jSRuntime; + + public IDBFactory(IJSRuntime jSRuntime) + { + this.jSRuntime = jSRuntime; + } + + private static ValueTask Import(IJSRuntime jsRuntime) + { + return module is null ? Execute() : new(module); + + async ValueTask Execute() => + module = await jsRuntime.InvokeAsync("import", "./js/indexed-wrapper.js"); + } + + public static async ValueTask Open(IJSRuntime jSRuntime, IDBDatabaseDefinition definition) + { + var module = await Import(jSRuntime); + var database = await module.InvokeAsync("open", definition); + var info = await database.InvokeAsync("getInfo"); + + var db = new IDBDatabase(jSRuntime, database, info.Name, info.Version, info.ObjectStoreNames); + return db; + } + + public static async ValueTask<(string Name, long Version)[]> Databases(IJSRuntime jSRuntime) + { + var module = await Import(jSRuntime); + var database = await module.InvokeAsync("databases"); + return [.. database.Select(d => (d.Name, d.Version))]; + } + + public static async ValueTask DeleteDatabase(IJSRuntime jSRuntime, string name) + { + var module = await Import(jSRuntime); + var result = await module.InvokeAsync("deleteDatabase", name); + return result; + } + + public static DotNetObjectReference? GetObjReferenceWrapper(T? value) where T : class + { + return value is { } ? DotNetObjectReference.Create(value) : null; + } + + private record IndexedDatabaseInfo(string Name, long Version, string[] ObjectStoreNames); + + private record IndexedDatabasesInfo(string Name, long Version); +} + +public sealed class IDBDatabase : IDBBase +{ + private bool closed; + private readonly ConcurrentDictionary stores = []; + + /// + /// A string that contains the name of the connected database. + /// + public string Name { get; } + + /// + /// The version of the connected database. + /// + public long Version { get; } + + /// + /// A string array containing the names of the object stores currently in the connected database. + /// + public string[] ObjectStoreNames { get; } + + public IDBDatabase(IJSRuntime jSRuntime, IJSObjectReference jsReference, string name, long version, string[] objectStoreNames) : base(jSRuntime, jsReference) + { + Name = name; + Version = version; + ObjectStoreNames = objectStoreNames; + } + + public ValueTask GetObjectStore(string name) + { + return stores.TryGetValue(name, out var store) ? new(store) : Execute(this, name); + + static async ValueTask Execute(IDBDatabase db, string name) + { + var objectStore = await db.JSReference.InvokeAsync("objectStore", name); + var info = await objectStore.InvokeAsync("getInfo"); + + var store = new IDBObjectStore(db.JSRuntime, objectStore, info.Name, info.KeyPath, info.AutoIncrement, info.IndexNames); + db.stores.TryAdd(name, store); + return store; + } + } + + public ValueTask Close() + { + return closed ? new() : Execute(this); + + static ValueTask Execute(IDBDatabase db) + { + db.closed = true; + return db.JSReference.InvokeVoidAsync("close"); + } + } + + public override ValueTask DisposeAsync() + { + return stores.IsEmpty + ? base.DisposeAsync() + : new ValueTask(Task.WhenAll(stores.Values.Select(s => s.DisposeAsync().AsTask()).Append(base.DisposeAsync().AsTask()))); + } + + private record IndexedObjectStoreInfo(string Name, string KeyPath, bool AutoIncrement, string[] IndexNames); +} + +public sealed class IDBObjectStore : IDBBase +{ + /// + /// The store name. + /// + public string Name { get; } + + /// + /// The store primary key path. + /// + public string KeyPath { get; } + + /// + /// Whether the key is auto incremented by the database. + /// + public bool AutoIncrement { get; } + + /// + /// A list with all the index names of the store. + /// + public string[] IndexNames { get; } + + public IDBObjectStore(IJSRuntime jSRuntime, IJSObjectReference jsReference, string name, string keyPath, bool autoIncrement, string[] indexNames) : base(jSRuntime, jsReference) + { + Name = name; + KeyPath = keyPath; + AutoIncrement = autoIncrement; + IndexNames = indexNames; + } + + public ValueTask Count() + { + return JSReference.InvokeAsync("count"); + } + + public ValueTask Get(TKey key) + { + return JSReference.InvokeAsync("get", key); + } + + public ValueTask Get(TKey key) + { + return JSReference.InvokeAsync("get", key); + } + + //public ValueTask GetKey() + //{ + // return JSReference.InvokeAsync("get", key); + //} + + //public ValueTask GetKey() + //{ + // return JSReference.InvokeAsync("get", key); + //} + + public ValueTask> GetAll() + { + return JSReference.InvokeAsync>("getAll"); + } + + public ValueTask> GetAll() + { + return JSReference.InvokeAsync>("getAll"); + } + + public ValueTask> GetAllKeys() + { + return JSReference.InvokeAsync>("getAllKeys"); + } + + public ValueTask> GetAllKeys() + { + return JSReference.InvokeAsync>("getAllKeys"); + } + + public ValueTask Add(T obj) + { + return JSReference.InvokeVoidAsync("add", obj); + } + + public ValueTask Put(T obj) + { + return JSReference.InvokeVoidAsync("put", obj); + } + + public ValueTask Delete(TKey key) + { + return JSReference.InvokeVoidAsync("delete", key); + } + + public ValueTask Clear() + { + return JSReference.InvokeVoidAsync("clear"); + } + + //public ValueTask OpenCursor() + //{ + //} + + //public ValueTask OpenKeyCursor() + //{ + //} +} diff --git a/src/TabKeeper.UI.Wasm/Common/LocalStorageConfigurationProvider.cs b/src/TabKeeper.UI.Wasm/Common/LocalStorageConfigurationProvider.cs new file mode 100644 index 0000000..402bd5d --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Common/LocalStorageConfigurationProvider.cs @@ -0,0 +1,46 @@ +using Blazored.LocalStorage; + +namespace TabKeeper.Common; + +public sealed class LocalStorageConfigurationProvider : ConfigurationProvider, IConfigurationSource +{ + private readonly ISyncLocalStorageService localStorage; + + public LocalStorageConfigurationProvider(ISyncLocalStorageService localStorage) + { + this.localStorage = localStorage; + } + + public override bool TryGet(string key, out string? value) + { + if (base.TryGet(key, out value)) + return true; + + value = localStorage.GetItemAsString(key); + if (value is null) + return false; + + base.Set(key, value); + return true; + } + + public override void Set(string key, string? value) + { + localStorage.SetItemAsString(key, value ?? string.Empty); + base.Set(key, value); + } + + public override void Load() + { + foreach (var key in localStorage.Keys()) + { + base.Set(key, localStorage.GetItemAsString(key)); + } + OnReload(); + } + + public IConfigurationProvider Build(IConfigurationBuilder builder) + { + return this; + } +} diff --git a/src/TabKeeper.UI.Wasm/Common/Migrations/IndexedDB_Migration_2024_08_001.cs b/src/TabKeeper.UI.Wasm/Common/Migrations/IndexedDB_Migration_2024_08_001.cs new file mode 100644 index 0000000..424c35d --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Common/Migrations/IndexedDB_Migration_2024_08_001.cs @@ -0,0 +1,91 @@ +using Blazored.LocalStorage; +using Microsoft.JSInterop; +using TabKeeper.Common.IndexedDB; +using TabKeeper.People; +using TabKeeper.Tabs; + +namespace TabKeeper.Common.Migrations; + +public sealed class IndexedDB_Migration_2024_08_001 +{ + private const string EntriesKey = "tab-entries"; + private readonly ISyncLocalStorageService localStorage; + private readonly StorageDb storage; + + public IndexedDB_Migration_2024_08_001(ISyncLocalStorageService localStorage, StorageDb storage) + { + this.localStorage = localStorage; + this.storage = storage; + } + + public async Task Migrate() + { + if (localStorage.GetItem(EntriesKey) is not { } tabs) + return; + + if (await storage.Tabs.Count() is not 0) + return; + + foreach (var tab in tabs) + { + await MigrateTab(tab); + localStorage.RemoveItem(tab.Id); + } + localStorage.RemoveItem(EntriesKey); + } + + private ValueTask MigrateTab(TabEntry entry) + { + if (localStorage.GetItem(entry.Id) is not { } tab) + return new(); + + var newTab = new Tab(tab.Id) + { + Name = tab.Name, + Place = string.IsNullOrEmpty(tab.Place) ? null : tab.Place, + Date = tab.Date, + Products = [.. tab.Products], + People = [.. tab.People.Select(x => new TabPerson(x.Person) { ProductIds = x.ProductIds })], + }; + return storage.Tabs.Add(newTab); + } + + private sealed record TabEntry(Uuid Id, string Name); + + private sealed record TabOld : IEntity + { + public required Uuid Id { get; init; } + + public string Name { get; set; } = string.Empty; + + public string Place { get; set; } = string.Empty; + + public DateOnly? Date { get; set; } + + public HashSet Products { get; set; } = []; + + public HashSet People { get; set; } = []; + } + + private sealed record PersonTabOld + { + public Person Person { get; } + + public HashSet ProductIds { get; init; } = []; + + public PersonTabOld(Person person) + { + Person = person; + } + + public override int GetHashCode() + { + return Person.Id.GetHashCode(); + } + + public bool Equals(PersonTabOld? other) + { + return Person.Id.Equals(other?.Person.Id); + } + } +} diff --git a/src/TabKeeper.UI.Wasm/Common/Mixins/TranslateMixins.cs b/src/TabKeeper.UI.Wasm/Common/Mixins/TranslateMixins.cs new file mode 100644 index 0000000..a5698cd --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Common/Mixins/TranslateMixins.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Components; +using System.Reactive.Disposables; + +namespace Annular.Translate; + +public static class TranslateMixins +{ + public static IDisposable Update(this TranslateService translate, IComponent component) + { + if (component is not IHandleEvent handleEvent) + return Disposable.Empty; + + var @ref = new WeakReference(handleEvent); + + return translate.OnLangChange + .Select(e => @ref.TryGetTarget(out var target) ? target : null) + .TakeUntil(static t => t is not null) + .Subscribe(static t => t?.HandleEventAsync(EventCallbackWorkItem.Empty, null)); + } + + public static IDisposable Update(this TranslateService translate, CoreComponent component) + { + var @ref = new WeakReference(component); + + return translate.OnLangChange + .Select(e => @ref.TryGetTarget(out var target) ? target : null) + .TakeUntil(static t => t is not null) + .Subscribe(static t => t?.Update()); + } +} diff --git a/src/TabKeeper.UI.Wasm/Common/StorageDb.cs b/src/TabKeeper.UI.Wasm/Common/StorageDb.cs new file mode 100644 index 0000000..7863673 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Common/StorageDb.cs @@ -0,0 +1,115 @@ +using Microsoft.JSInterop; +using TabKeeper.Common.IndexedDB; +using TabKeeper.People; +using TabKeeper.Tabs; + +namespace TabKeeper.Common; + +public static class StorageDefinitions +{ + public static readonly IDBDatabaseDefinition TabKeeper_v1 = new() + { + Name = "TabKeeper", + Version = 1, + ObjectStores = + [ + new() + { + Name = "People", + KeyPath = "id", + Indexes = [ + new() { Name = "Name", KeyPath = "name" }, + ] + }, + new() + { + Name = "Tabs", + KeyPath = "id", + Indexes = [ + new() { Name = "Name", KeyPath = "name" }, + new() { Name = "Place", KeyPath = "place" }, + new() { Name = "PayerId", KeyPath = "payerId" }, + new() { Name = "Date", KeyPath = "date" }, + new() { Name = "IsLocked", KeyPath = "isLocked" }, + ] + }, + ] + }; +} + +public sealed class StorageDb : IAsyncDisposable +{ + private readonly IJSRuntime jSRuntime; + private IDBDatabase db = null!; + + public StorageDb(IJSRuntime jSRuntime) + { + this.jSRuntime = jSRuntime; + } + + public async Task Initialize() + { + db = await IDBFactory.Open(jSRuntime, StorageDefinitions.TabKeeper_v1); + Tabs = new(await db.GetObjectStore("Tabs")); + People = new(await db.GetObjectStore("People")); + } + + public StorageStore Tabs { get; private set; } = null!; + + public StorageStore People { get; private set; } = null!; + + public ValueTask DisposeAsync() + { + return db?.DisposeAsync() ?? new(); + } +} + +public sealed class StorageStore +{ + private readonly IDBObjectStore store; + + public StorageStore(IDBObjectStore store) + { + this.store = store; + } + + public ValueTask Count() + { + return store.Count(); + } + + public ValueTask Get(TKey key) + { + return store.Get(key); + } + + public ValueTask> GetAll() + { + return store.GetAll(); + } + + public ValueTask> GetAllKeys() + { + return store.GetAllKeys(); + } + + public ValueTask Add(T obj) + { + return store.Add(obj); + } + + public ValueTask Put(T obj) + { + return store.Put(obj); + } + + public ValueTask Delete(TKey key) + { + return store.Delete(key); + } + + public ValueTask Clear() + { + return store.Clear(); + } +} diff --git a/src/TabKeeper.UI.Wasm/Common/ThemeModule.cs b/src/TabKeeper.UI.Wasm/Common/ThemeModule.cs new file mode 100644 index 0000000..8dfd5b6 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Common/ThemeModule.cs @@ -0,0 +1,38 @@ +using System.Runtime.InteropServices.JavaScript; +using System.Runtime.Versioning; + +namespace TabKeeper; + +[SupportedOSPlatform("browser")] +public static partial class ThemeModule +{ + private const string name = nameof(ThemeModule); + private static int imported; + + public static Task Import(string? url = null) + { + if (Interlocked.Exchange(ref imported, 1) is 1) + return Task.CompletedTask; + + // JSHost starts searching from inside _framework folder so we have to go one up for default. + return JSHost.ImportAsync(name, url ?? "../js/theme.js"); + } + + [JSImport("updateDom", name)] + public static partial void UpdateDom(); + + [JSImport("toggle", name)] + public static partial void Toggle(); + + [JSImport("setDark", name)] + public static partial void SetDark(); + + [JSImport("setLight", name)] + public static partial void SetLight(); + + [JSImport("setAuto", name)] + public static partial void SetAuto(); + + [JSImport("getTheme", name)] + public static partial string GetTheme(); +} diff --git a/src/TabKeeper.UI.Wasm/Components/Anchor.cs b/src/TabKeeper.UI.Wasm/Components/Anchor.cs new file mode 100644 index 0000000..f8e8c05 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Components/Anchor.cs @@ -0,0 +1,11 @@ +namespace TabKeeper.Components; + +[Flags] +public enum Anchor +{ + Bottom = 1 << 0, + Top = 1 << 1, + Left = 1 << 2, + Right = 1 << 3, + Center = 1 << 4 +} diff --git a/src/TabKeeper.UI.Wasm/Components/Button.razor b/src/TabKeeper.UI.Wasm/Components/Button.razor index 5fb8bf8..5e5baa8 100644 --- a/src/TabKeeper.UI.Wasm/Components/Button.razor +++ b/src/TabKeeper.UI.Wasm/Components/Button.razor @@ -1,7 +1,9 @@ -@using System.Diagnostics.CodeAnalysis -@using System.Globalization +@inherits CoreComponent -@inherits CoreComponent +@if (If is false) +{ + return; +} + + +@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [Parameter] + public EventCallback OnClick { get; set; } +} diff --git a/src/TabKeeper.UI.Wasm/Components/Js.cs b/src/TabKeeper.UI.Wasm/Components/Js.cs deleted file mode 100644 index 060f32b..0000000 --- a/src/TabKeeper.UI.Wasm/Components/Js.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.JSInterop; - -namespace TabKeeper.Components; - -public class Js -{ -} - -public class Window -{ -} diff --git a/src/TabKeeper.UI.Wasm/Components/LottiePlayer.cs b/src/TabKeeper.UI.Wasm/Components/LottiePlayer.cs new file mode 100644 index 0000000..0298d44 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Components/LottiePlayer.cs @@ -0,0 +1,109 @@ +using Core.Blazor; +using Microsoft.AspNetCore.Components; + +namespace TabKeeper.Components; + +public partial class LottiePlayer : CoreComponent +{ + /// + /// The animation to play, either Bodymovin JSON data or a URL to a JSON file. + /// + /// This parameter is mandatory. + [Parameter, EditorRequired] + public string Source { get; set; } = string.Empty; + + /// + /// Number of times to loop the animation + /// + [Parameter] + public int? Count { get; set; } + + /// + /// Duration (in milliseconds) to pause before playing each cycle in a looped animation. + /// + /// Set this parameter to 0 (no pause) or any positive number. + [Parameter] + public int Intermission { get; set; } = 1; + + /// + /// Animation speed. + /// + /// Set this parameter to any positive number. + [Parameter] + public int Speed { get; set; } = 1; + + /// + /// Direction of the animation. Set to 1 to play the animation forward or set to -1 to play it backward. + /// + /// 1 or -1 + [Parameter] + public LottieDirection Direction { get; set; } = LottieDirection.Forward; + + /// + /// Background color. By default, the background is transparent and will take the color of the parent container. + /// + [Parameter] + public string? Background { get; set; } + + /// + /// When set to , loops the animation. The property defines the number of times to loop the animation. + /// + /// Setting the property to 0 and setting to , loops the animation indefinitely. + [Parameter] + public bool Loop { get; set; } + + /// + /// When set to , displays player controls. + /// + [Parameter] + public bool Controls { get; set; } + + /// + /// Play mode. Setting the mode to plays the animation in an indefinite cycle, forwards and then backwards. + /// + [Parameter] + public LottiePlayMode Mode { get; set; } = LottiePlayMode.Normal; + + /// + /// The renderer to use for the animation + /// + /// 'svg', 'html' or 'canvas' + [Parameter] + public string Renderer { get; set; } = "svg"; + + /// + /// Disables verification of the Lottie animation before loading it. + /// + [Parameter] + public bool DisableCheck { get; set; } + + /// + /// When set to , plays animation on mouse over + /// + [Parameter] + public bool Hover { get; set; } + + /// + /// When set to , automatically plays the animation on loading it. + /// + [Parameter] + public bool AutoPlay { get; set; } + + /// + /// Valid value to preserve the aspect ratio. See the Mozilla documentation for more information. + /// + [Parameter] + public string PreserveAspectRatio { get; set; } = string.Empty; +} + +public enum LottieDirection +{ + Forward = 1, + Backward = -1, +} + +public enum LottiePlayMode +{ + Normal, + Bounce +} diff --git a/src/TabKeeper.UI.Wasm/Components/LottiePlayer.razor b/src/TabKeeper.UI.Wasm/Components/LottiePlayer.razor new file mode 100644 index 0000000..d2ce2e3 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Components/LottiePlayer.razor @@ -0,0 +1,18 @@ +@inherits CoreComponent + + + diff --git a/src/TabKeeper.UI.Wasm/Components/Modal.razor b/src/TabKeeper.UI.Wasm/Components/Modal.razor index a53a5f6..ffe120b 100644 --- a/src/TabKeeper.UI.Wasm/Components/Modal.razor +++ b/src/TabKeeper.UI.Wasm/Components/Modal.razor @@ -13,11 +13,11 @@ LeaveTo="opacity-0" Context="transition"> -
+
-
+
-
("class") ?? "self-center justify-self-center", transition.CssClass)" @onclick:stopPropagation> - - @(ChildContent?.Invoke(this)) - +
+ @(ChildContent?.Invoke(this))
@@ -41,8 +39,6 @@ @code { - private ReactiveValue updateExpression; - [Parameter] public bool IsOpen { get; set; } @@ -67,11 +63,6 @@ [Parameter] public EventCallback OnShow { get; set; } - public Modal() - { - updateExpression = new(this, 0); - } - protected override void OnInitialized() { if (IsOpenWhen is { }) @@ -85,7 +76,7 @@ } if (UpdateWhen is { }) { - var updateSub = UpdateWhen.Subscribe(_ => updateExpression.Value = 0); + var updateSub = UpdateWhen.Subscribe(_ => Update()); DisposeWith(updateSub); } } @@ -110,9 +101,4 @@ { return IsOpen ? Close() : Show(); } - - public void Update() - { - updateExpression.Value = 0; - } } diff --git a/src/TabKeeper.UI.Wasm/Components/NotFound.razor b/src/TabKeeper.UI.Wasm/Components/NotFound.razor new file mode 100644 index 0000000..92a8990 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Components/NotFound.razor @@ -0,0 +1,6 @@ +@inject TranslateService translate + + diff --git a/src/TabKeeper.UI.Wasm/Components/People/PersonCircleView.razor b/src/TabKeeper.UI.Wasm/Components/People/PersonCircleView.razor deleted file mode 100644 index c498440..0000000 --- a/src/TabKeeper.UI.Wasm/Components/People/PersonCircleView.razor +++ /dev/null @@ -1,13 +0,0 @@ -@inherits CoreRxComponent - -
-

@ViewModel.Name

- -
- @ViewModel.Total -
-
- -@code { - -} diff --git a/src/TabKeeper.UI.Wasm/Components/People/PersonView.razor b/src/TabKeeper.UI.Wasm/Components/People/PersonView.razor deleted file mode 100644 index 32fe0cb..0000000 --- a/src/TabKeeper.UI.Wasm/Components/People/PersonView.razor +++ /dev/null @@ -1,6 +0,0 @@ -@inherits CoreRxComponent - - - -@code { -} diff --git a/src/TabKeeper.UI.Wasm/Components/People/_imports.razor b/src/TabKeeper.UI.Wasm/Components/People/_imports.razor deleted file mode 100644 index ad939fc..0000000 --- a/src/TabKeeper.UI.Wasm/Components/People/_imports.razor +++ /dev/null @@ -1 +0,0 @@ -@using TabKeeper.People \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/Components/RxComponents/RxErrors.razor b/src/TabKeeper.UI.Wasm/Components/RxComponents/RxErrors.razor deleted file mode 100644 index 0a371e2..0000000 --- a/src/TabKeeper.UI.Wasm/Components/RxComponents/RxErrors.razor +++ /dev/null @@ -1,24 +0,0 @@ - -@if (ShowErrors && EditContext?.IsValid(FieldIdentifier) is false) -{ - @foreach (var error in EditContext?.GetValidationMessages(this.FieldIdentifier) ?? []) - { -

@error

- } -} - -@code { - [CascadingParameter] - public EditContext? EditContext { get; set; } - - [Parameter, EditorRequired] - public FieldIdentifier FieldIdentifier { get; set; } - - [Parameter] - public bool ShowErrors { get; set; } = true; - - /// - /// Gets or sets a collection of additional attributes that will be applied to the created element. - /// - [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary? AdditionalAttributes { get; set; } -} diff --git a/src/TabKeeper.UI.Wasm/Components/RxComponents/RxInput.cs b/src/TabKeeper.UI.Wasm/Components/RxComponents/RxInput.cs deleted file mode 100644 index bc43bd9..0000000 --- a/src/TabKeeper.UI.Wasm/Components/RxComponents/RxInput.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace TabKeeper.Components.RxComponents; - -public static class RxInput -{ - public static class Types - { - public const string Text = "text"; - - public const string Password = "password"; - - public const string Number = "number"; - - public const string Button = "button"; - - public const string Checkbox = "checkbox"; - - public const string Color = "color"; - - public const string Date = "date"; - - public const string DatetimeLocal = "datetime-local"; - - public const string Email = "email"; - - public const string File = "file"; - - public const string Hidden = "hidden"; - - public const string Image = "image"; - - public const string Month = "month"; - - public const string Radio = "radio"; - - public const string Range = "range"; - - public const string Reset = "reset"; - - public const string Search = "search"; - - public const string Submit = "submit"; - - public const string Tel = "tel"; - - public const string Time = "time"; - - public const string Url = "url"; - - public const string Week = "week"; - } -} diff --git a/src/TabKeeper.UI.Wasm/Components/RxComponents/RxInput.razor b/src/TabKeeper.UI.Wasm/Components/RxComponents/RxInput.razor deleted file mode 100644 index 096b6e7..0000000 --- a/src/TabKeeper.UI.Wasm/Components/RxComponents/RxInput.razor +++ /dev/null @@ -1,74 +0,0 @@ -@using System.Diagnostics.CodeAnalysis -@using System.Globalization - -@inherits InputBase -@typeparam T where T : IParsable - - - -@if (!string.IsNullOrEmpty(Label)) -{ - -} - - - -@code { - [Parameter] - public string? Label { get; set; } - - [Parameter] - public string? Name { get; set; } - - [Parameter] - public bool ShowErrors { get; set; } = true; - - [Parameter] - public string BindEvent { get; set; } = "onchange"; - - /// - protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out T result, [NotNullWhen(false)] out string? validationErrorMessage) - { - (result, validationErrorMessage) = (default, null); - try - { - result = T.Parse(value ?? string.Empty, null); - return true; - } - catch (Exception ex) - { - validationErrorMessage = ex.Message; - } - return false; - } - - protected override string? FormatValueAsString(T? value) - { - return base.FormatValueAsString(value); - } - - private string Id => GetAttribute("id", NameAttributeValue); - - private string Type => GetAttribute("type", RxInput.Types.Text); - - private string? Placeholder => GetAttribute("placeholder", Label); - - private string? LabelClass => GetAttribute("label-class", null); - - private string? ErrorClass => GetAttribute("error-class", null); - - [return: NotNullIfNotNull(nameof(defaultValue))] - private string? GetAttribute(string key, string? defaultValue) - => AdditionalAttributes?.TryGetValue(key, out var value) is true - ? Convert.ToString(value, CultureInfo.InvariantCulture) ?? defaultValue - : defaultValue; -} diff --git a/src/TabKeeper.UI.Wasm/Layout/ShellContext.cs b/src/TabKeeper.UI.Wasm/Layout/ShellContext.cs new file mode 100644 index 0000000..41279fb --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Layout/ShellContext.cs @@ -0,0 +1,13 @@ +namespace TabKeeper.Layout; + +public readonly record struct ShellContext +{ + public string Title { get; init; } + + public string? BackUri { get; init; } + + public ShellContext() + { + Title = string.Empty; + } +} diff --git a/src/TabKeeper.UI.Wasm/Layout/ShellLayout.razor b/src/TabKeeper.UI.Wasm/Layout/ShellLayout.razor index f1120e1..10e461c 100644 --- a/src/TabKeeper.UI.Wasm/Layout/ShellLayout.razor +++ b/src/TabKeeper.UI.Wasm/Layout/ShellLayout.razor @@ -1,12 +1,62 @@ @inherits LayoutComponentBase +@implements IDisposable -
- Home +@inject TranslateService translate +@inject NavigationManager nav + +@if (ThisAssembly.IsPrerelease) +{ + +} + +@(string.IsNullOrEmpty(Title) ? "Tab Keeper" : $"Tab Keeper - {Title}") + +
+ +

@Title

-
+
@Body
-@*
-
*@ +@code { + private static readonly BehaviorSubject contextSub = new(new()); + private IDisposable? sub; + + protected override void OnInitialized() + { + sub = contextSub.Subscribe(_ => StateHasChanged()); + } + + public static IObservable ContextChanged { get; } = contextSub.AsObservable(); + + public static ShellContext Context + { + get => contextSub.Value; + set { + if (contextSub.Value == value) return; + contextSub.OnNext(value); + } + } + + public static string Title + { + get => Context.Title; + } + + public static string? BackUri + { + get => Context.BackUri; + } + + public void Dispose() + { + sub?.Dispose(); + sub = null; + } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/Home/HomePage.razor b/src/TabKeeper.UI.Wasm/Pages/Home/HomePage.razor deleted file mode 100644 index 9632eec..0000000 --- a/src/TabKeeper.UI.Wasm/Pages/Home/HomePage.razor +++ /dev/null @@ -1,79 +0,0 @@ -@page "/" -@inherits CoreComponent -@inject ISyncLocalStorageService storage -@inject NavigationManager nav - -
-
- @foreach(var entry in Entries.Items) - { -
-

@entry.Name

- - - - -
- } -
- - -
- - - - -
- -
- - @if (NewTabEntryName.Value.Length < 3) - { - Name can't be less than 3 characters - } - - -
-
- -@code { - private const string EntriesKey = "tab-entries"; - private Modal addEntryModal = null!; - - private BehaviorSubject NewTabEntryName { get; } = new(""); - - private SourceList Entries { get; } = new(); - - private void AddNewTab() - { - if (NewTabEntryName.Value.Length < 3) return; - - var entryId = Uuid.NewUuid(); - Entries.Insert(0, new TabEntry(entryId, NewTabEntryName.Value)); - nav.NavigateTo($"/tabs/{entryId}"); - } - - protected override void OnInitialized() - { - NewTabEntryName.Subscribe(_ => Update()); - Entries - .Connect() - .OnItemAdded(entry => storage.TrySetItem(entry.Id, new TabKeeper.Tabs.Tab { Id = entry.Id, Name = entry.Name })) - .OnItemRemoved(entry => storage.RemoveItem(entry.Id), invokeOnUnsubscribe: false) - .QueryWhenChanged() - .Do(entries => storage.SetItem(EntriesKey, entries)) - .Subscribe(_ => Update()) - .DisposeWith(Disposables); - - - Entries.AddRange(storage.GetItem>(EntriesKey) ?? []); - } - - private record TabEntry(Uuid Id, string Name); -} diff --git a/src/TabKeeper.UI.Wasm/Pages/HomePage.razor b/src/TabKeeper.UI.Wasm/Pages/HomePage.razor new file mode 100644 index 0000000..8b75ca9 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/HomePage.razor @@ -0,0 +1,82 @@ +@page "/" +@inherits CoreComponent +@inject StorageDb db +@inject NavigationManager nav +@inject TranslateService translate + +
+ @* Tabs *@ +
+ @foreach(var entry in Entries.Items.OrderBy(x => x.Date)) + { + +

@entry.Name

+
+ } +
+ + @* Bar *@ +
+ + + + + + @("settings.title" | translate) + + + + +
+
+ + + + + + +@code { + private Modal addEntryModal = null!; + private SourceList Entries { get; } = new(); + private bool loading = true; + + private async Task TabValidSubmit(TabKeeper.Tabs.Tab tab) + { + await db.Tabs.Add(tab); + nav.NavigateTo($"tab/{tab.Id}"); + } + + protected override void OnAfterRender(bool firstRender) + { + if (!firstRender) return; + + ShellLayout.Context = new() { Title = "general.home" | translate }; + + db.Tabs + .GetAll() + .AsTask() + .ToObservable() + .Do(entries => + { + Entries.AddRange(entries.Select(x => new TabEntry(x.Id, x.Name, x.Date))); + Entries + .Connect() + .OnItemRemoved(async entry => await db.Tabs.Delete(entry.Id), invokeOnUnsubscribe: false) + .Subscribe(_ => Update()) + .DisposeWith(this); + loading = false; + }) + .Subscribe(_ => Update()) + .DisposeWith(this); + } + + private record TabEntry(Uuid Id, string Name, DateOnly? Date); +} diff --git a/src/TabKeeper.UI.Wasm/Pages/People/Components/PersonForm.razor b/src/TabKeeper.UI.Wasm/Pages/People/Components/PersonForm.razor new file mode 100644 index 0000000..0d21587 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/People/Components/PersonForm.razor @@ -0,0 +1,42 @@ +@inherits CoreComponent +@inject TranslateService translate + + + + +
+ + +
+ + +
+ +@code { + [Parameter, NotNull] + public Person? Person { get; set; } + + [Parameter] + public bool OnValidReset { get; set; } + + [Parameter] + public EventCallback OnValidSubmit { get; set; } + + public void Reset() + { + Person = new(); + Update(); + } + + protected override void OnInitialized() + { + Person ??= new(); + } + + private void ValidSubmit() + { + OnValidSubmit.InvokeAsync(Person); + if (OnValidReset) + Reset(); + } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/People/_imports.razor b/src/TabKeeper.UI.Wasm/Pages/People/_imports.razor new file mode 100644 index 0000000..4b3a7b3 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/People/_imports.razor @@ -0,0 +1,2 @@ +@using TabKeeper.People +@using TabKeeper.Pages.People.Components diff --git a/src/TabKeeper.UI.Wasm/Pages/SettingsPage.razor b/src/TabKeeper.UI.Wasm/Pages/SettingsPage.razor new file mode 100644 index 0000000..10154d7 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/SettingsPage.razor @@ -0,0 +1,31 @@ +@using Core.Preferences +@using Core.Preferences.Controls +@using Core.Preferences.Pages +@using Microsoft.Extensions.Configuration.Memory + +@page "/settings" +@inherits CoreComponent +@inject TranslateService translate +@inject PreferenceManager manager + + + +@code { + public static ConfigurationManager Configuration { get; } = new(); + + protected override void OnInitialized() + { + ShellLayout.Context = new() { Title = "settings.title" | translate }; + Preferences.Screen.TitleTransformer = v => v | translate; + Preferences.Screen.DescriptionTransformer = v => v is { } ? v | translate : v; + Preferences.Screen.SummaryTransformer = v => v | translate; + + Preferences.Screen + .WhenValuePreferenceChanged(Preferences.Theme) + .Throttle(TimeSpan.FromMilliseconds(100)) + .Subscribe(p => ThemeModule.UpdateDom()) + .DisposeWith(this); + + Preferences.Screen.Initialize(Configuration); + } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/PersonCardView.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/PersonCardView.razor new file mode 100644 index 0000000..480c84f --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/PersonCardView.razor @@ -0,0 +1,16 @@ +@inherits CoreRxComponent + +
+

+ @ViewModel.Name +

+
+ +

@(ViewModel.Total.ToString("0.00"))

+
+
+ +@code { + [Parameter] + public EventCallback OnClick { get; set; } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/PersonDetailView.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/PersonDetailView.razor new file mode 100644 index 0000000..41f27c4 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/PersonDetailView.razor @@ -0,0 +1,65 @@ +@inherits CoreRxComponent +@inject TranslateService translate + +
+
+

+ @ViewModel.Name +

+ +
+ @if (edit) + { + +
+ + +
+ } + else + { + @foreach (var product in TabViewModel.Products.Items) + { + var key = product.ProductId.ToString(); + +
+ + +
+ } + } +
+ +@code { + private bool edit; + + [Parameter, EditorRequired] + public TabViewModel TabViewModel { get; set; } = null!; + + private void StartEdit() + { + edit = true; + Update(); + } + + private void CancelEdit() + { + edit = false; + Update(); + } + + private void ValidSubmit(Person person) + { + ViewModel.Person = person; + edit = false; + Update(); + } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductCardView.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductCardView.razor new file mode 100644 index 0000000..c58c37c --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductCardView.razor @@ -0,0 +1,36 @@ +@inherits CoreRxComponent + +
+
+

+ @ViewModel.Name +

+
+

@ViewModel.Price.ToString("0.00")

+ +
+
+ +
+

@ViewModel.Quantity

+ + +

@ViewModel.Total.ToString("0.00")

+ +
+ +
+ + + +
+
+ +@code { + [Parameter] + public EventCallback OnClick { get; set; } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductDetailView.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductDetailView.razor new file mode 100644 index 0000000..76b0c41 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductDetailView.razor @@ -0,0 +1,65 @@ +@inherits CoreRxComponent +@inject TranslateService translate + +
+
+

+ @ViewModel.Name +

+ +
+ @if (edit) + { + +
+ + +
+ } + else + { + @foreach (var person in TabViewModel.People.Items) + { + var key = person.PersonId.ToString(); + +
+ + +
+ } + } +
+ +@code { + private bool edit; + + [Parameter, EditorRequired] + public TabViewModel TabViewModel { get; set; } = null!; + + private void StartEdit() + { + edit = true; + Update(); + } + + private void CancelEdit() + { + edit = false; + Update(); + } + + private void ValidSubmit(TabProduct product) + { + ViewModel.Product = product; + edit = false; + Update(); + } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductForm.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductForm.razor new file mode 100644 index 0000000..2f1c005 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/ProductForm.razor @@ -0,0 +1,53 @@ +@inherits CoreComponent +@inject TranslateService translate + + + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ +@code { + [Parameter, NotNull] + public TabProduct? Product { get; set; } + + [Parameter] + public bool OnValidReset { get; set; } + + [Parameter] + public EventCallback OnValidSubmit { get; set; } + + public void Reset() + { + Product = new(); + Update(); + } + + protected override void OnInitialized() + { + Product ??= new(); + } + + private void ValidSubmit() + { + OnValidSubmit.InvokeAsync(Product); + if (OnValidReset) + Reset(); + } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/TabForm.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/TabForm.razor new file mode 100644 index 0000000..dcb552e --- /dev/null +++ b/src/TabKeeper.UI.Wasm/Pages/Tabs/Components/TabForm.razor @@ -0,0 +1,37 @@ +@inherits CoreComponent +@inject TranslateService translate + + + + +
+ + +
+ + +
+ + +
+ +
+ +@code { + [Parameter, NotNull] + public TabKeeper.Tabs.Tab? Tab { get; set; } + + [Parameter] + public EventCallback OnValidSubmit { get; set; } + + protected override void OnInitialized() + { + Tab ??= new(); + Tab.Date = DateOnly.FromDateTime(DateTimeOffset.Now.DateTime); + } + + private void ValidSubmit() + { + OnValidSubmit.InvokeAsync(Tab); + } +} diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/PersonCardView.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/PersonCardView.razor deleted file mode 100644 index 1b79fcc..0000000 --- a/src/TabKeeper.UI.Wasm/Pages/Tabs/PersonCardView.razor +++ /dev/null @@ -1,28 +0,0 @@ -@inherits CoreRxComponent - -
-
-

@ViewModel.Name

- - -
-
-
- -

@(ViewModel.Total.ToString("0.00"))

-
- -
-
- -@code { - [Parameter] - public EventCallback OnEditClicked { get; set; } - - [Parameter] - public EventCallback OnRemoveClicked { get; set; } -} \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/ProductCardView.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/ProductCardView.razor deleted file mode 100644 index 36f22da..0000000 --- a/src/TabKeeper.UI.Wasm/Pages/Tabs/ProductCardView.razor +++ /dev/null @@ -1,49 +0,0 @@ -@inherits CoreRxComponent - -
-
-
- -

@ViewModel.Name

-
-
- -

@ViewModel.Price

-
- -
-
-
- -

@ViewModel.Quantity

-
-
- -

@ViewModel.Total

-
-
- -

@ViewModel.Divisor

-
- - - - -
-
- -@code { - [Parameter] - public EventCallback OnEditClicked { get; set; } - - [Parameter] - public EventCallback OnRemoveClicked { get; set; } -} \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/TabPage.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/TabPage.razor index d5a8d67..923f347 100644 --- a/src/TabKeeper.UI.Wasm/Pages/Tabs/TabPage.razor +++ b/src/TabKeeper.UI.Wasm/Pages/Tabs/TabPage.razor @@ -1,11 +1,31 @@ -@page "/tabs/{Id}" - +@page "/tab/{Id}" @inherits CoreRxComponent +@inject StorageDb db +@inject TranslateService translate + +@* Loading *@ +@if (loading) +{ +
+
+ +
+
+ return; +} -@inject ISyncLocalStorageService storage - -Tab Keeper +@* Not Found *@ +@if (ViewModel is null) +{ +
+
+ +
+
+ return; +} +@* Found *@
@@ -17,8 +37,7 @@ }
@@ -31,39 +50,49 @@ }
-
- - - Products - - - People - - +
+
+
+ +

@ViewModel.Total.ToString("0.00")

+
-
-
- -

@ViewModel.Products.Items.Sum(x => x.Total)

-
- -

@ViewModel.People.Items.Sum(x => x.Total)

+
+ +

@ViewModel.People.Items.Sum(x => x.Total).ToString("0.00")

- - *@ + + + +
+ + + + + @("products" | translate) + + + + + @("people" | translate) + +
@@ -73,21 +102,11 @@ @{ var product = SelectedProduct.Value!; } - -
-

@product.Name

- -
- - @foreach (var person in ViewModel.People.Items) - { - var key = person.PersonId.ToString(); -
- - -
- } - + + @* Person Modal *@ @@ -95,108 +114,87 @@ @{ var person = SelectedPerson.Value!; } - -
-

@person.Name

- -
- - @foreach (var product in ViewModel.Products.Items) - { - var key = product.ProductId.ToString(); -
- - -
- } - + + @* Add Product Modal *@ - - @if (NewProduct.Value is null) { return; } - - - - -
- -
- -
- -
- - -
+ + +
+ + +
@* Add Person Modal *@ - - @if (NewPerson.Value is null) { return; } - - - - -
- -
- - -
+ + +
+ + +
@code { - public override TabViewModel ViewModel { get; set; } = null!; + private bool loading = true; + + private BehaviorSubject SelectedProduct { get; } = new(null); + private BehaviorSubject SelectedPerson { get; } = new(null); + + private Modal NewProductModal { get; set; } = null!; + private Modal NewPersonModal { get; set; } = null!; [Parameter] public string Id { get; set; } = string.Empty; - private void OnAddProduct() + private void OnValidProduct(TabProduct product) { - ViewModel.AddProduct(NewProduct!.Value); - NewProduct.OnNext(new()); + ViewModel.AddProduct(new(product)); } - private void OnAddPerson() + private void OnValidPerson(Person person) { - ViewModel.AddPerson(NewPerson!.Value); - NewPerson.OnNext(new()); + ViewModel.AddPerson(new(new TabPerson(person))); } - private BehaviorSubject SelectedProduct { get; } = new(null); - private BehaviorSubject SelectedPerson { get; } = new(null); - private BehaviorSubject NewProduct { get; } = new(null); - private BehaviorSubject NewPerson { get; } = new(null); - - protected override void OnInitialized() + protected override void OnAfterRender(bool firstRender) { - var tab = storage.GetItem(Id); - if (tab is null) - { - return; - } - - ViewModel = new TabViewModel(tab); - ViewModel.WhenPropertyChanged - .Throttle(TimeSpan.FromSeconds(1)) - .Subscribe(_ => + if (!firstRender) return; + + db.Tabs + .Get(Uuid.Parse(Id)) + .AsTask() + .ToObservable() + .Subscribe(tab => { - var tab = ViewModel.Tab; - tab.People.Clear(); - tab.People.AddRange(ViewModel.People.Items.Select(x => new PersonTab(new() { Id = x.PersonId, Name = x.Name }) - { - ProductIds = [.. x.ProductIds] - })); - tab.Products.Clear(); - tab.Products.AddRange(ViewModel.Products.Items.Select(x => new Product - { - Id = x.ProductId, - Name = x.Name, - Price = x.Price, - Quantity = x.Quantity - })); - storage.SetItem(tab.Id, tab); - }); + if (tab is null) return; + + ShellLayout.Context = new() { Title = tab.Name, BackUri = "" }; + ViewModel = new TabViewModel(tab); + ViewModel.WhenPropertyChanged + .Throttle(TimeSpan.FromMilliseconds(500)) + .Subscribe(async _ => await db.Tabs.Put(ViewModel.Tab)) + .DisposeWith(this); + + loading = false; + Update(); + }) + .DisposeWith(this); } } diff --git a/src/TabKeeper.UI.Wasm/Pages/Tabs/_imports.razor b/src/TabKeeper.UI.Wasm/Pages/Tabs/_imports.razor index e123412..02c23b0 100644 --- a/src/TabKeeper.UI.Wasm/Pages/Tabs/_imports.razor +++ b/src/TabKeeper.UI.Wasm/Pages/Tabs/_imports.razor @@ -1 +1,4 @@ -@using TabKeeper.Tabs \ No newline at end of file +@using TabKeeper.Tabs +@using TabKeeper.Pages.Tabs.Components +@using TabKeeper.Pages.People.Components +@using TabKeeper.People \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/Program.cs b/src/TabKeeper.UI.Wasm/Program.cs index d3f1829..46f847e 100644 --- a/src/TabKeeper.UI.Wasm/Program.cs +++ b/src/TabKeeper.UI.Wasm/Program.cs @@ -1,8 +1,16 @@ +using Annular.Translate; +using Annular.Translate.Abstract; +using Annular.Translate.HttpLoader; using Blazored.LocalStorage; +using Core.Preferences; using Ignis.Components.HeadlessUI; using Ignis.Components.WebAssembly; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.JSInterop; +using System.Diagnostics.CodeAnalysis; +using TabKeeper.Common; +using TabKeeper.Common.Migrations; var builder = WebAssemblyHostBuilder.CreateDefault(args); var services = builder.Services; @@ -15,4 +23,58 @@ services.AddIgnisWebAssembly(); services.AddBlazoredLocalStorage(c => c.JsonSerializerOptions = Options.Json); -await builder.Build().RunAsync(); +services.AddScoped(sp => new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +services.AddScoped(sp => (IJSInProcessRuntime)sp.GetRequiredService()); + +services.AddScoped(); +services.AddScoped(); + +services.AddScoped(); +services.AddScoped(sp => +{ + var localStorage = sp.GetRequiredService(); + var manager = new PreferenceManager(); + manager.Sources.Add(localStorage); + return manager; +}); + +services.AddScoped(); +services.AddScoped(); + +var app = builder.Build(); + +await Import(); +await InitializeLang(app); + +var storage = app.Services.GetRequiredService(); +await storage.Initialize(); + +var migration = app.Services.GetRequiredService(); +await migration.Migrate(); + +await app.RunAsync(); + +[SuppressMessage("BrowserPlatform", "CA1416")] +static Task Import() +{ + return ThemeModule.Import(); +} + +static Task InitializeLang(WebAssemblyHost app) +{ + var localStorage = app.Services.GetRequiredService(); + var js = app.Services.GetRequiredService(); + var translate = app.Services.GetRequiredService(); + + translate.Langs.AddRange(["en", "el"]); + + var lang = localStorage.GetItem("lang"); + lang ??= js.GetBrowserLang(); + + if (lang is null || !translate.Langs.Contains(lang)) + { + lang = "en"; + } + localStorage.SetItemAsString("lang", lang); + return translate.SetCurrentLang(lang).ToTask(); +} diff --git a/src/TabKeeper.UI.Wasm/Properties/launchSettings.json b/src/TabKeeper.UI.Wasm/Properties/launchSettings.json index bbe560b..f262aa1 100644 --- a/src/TabKeeper.UI.Wasm/Properties/launchSettings.json +++ b/src/TabKeeper.UI.Wasm/Properties/launchSettings.json @@ -1,27 +1,11 @@ { - "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { - "run": { + "TabKeeper.UI.Wasm": { "commandName": "Project", - "launchBrowser": false, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "applicationUrl": "https://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "watch": { - "commandName": "Executable", - "executablePath": "dotnet.exe", - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "workingDirectory": "$(ProjectDir)", - "commandLineArgs": "watch --non-interactive run", - "launchBrowser": false, - "applicationUrl": "https://localhost:5001", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "ASPNETCORE_HTTPS_PORT": "5001" - } + }, + "applicationUrl": "https://localhost:5001" } } -} +} \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/TabKeeper.UI.Wasm.csproj b/src/TabKeeper.UI.Wasm/TabKeeper.UI.Wasm.csproj index d4809d3..984a555 100644 --- a/src/TabKeeper.UI.Wasm/TabKeeper.UI.Wasm.csproj +++ b/src/TabKeeper.UI.Wasm/TabKeeper.UI.Wasm.csproj @@ -1,23 +1,25 @@  - net8.0 + net9.0 TabKeeper + true + true - - - - - - - - - + + + + + + + + + @@ -25,13 +27,4 @@ - - - - - - - - - diff --git a/src/TabKeeper.UI.Wasm/_Imports.razor b/src/TabKeeper.UI.Wasm/_Imports.razor index 2b73bc7..dd590cf 100644 --- a/src/TabKeeper.UI.Wasm/_Imports.razor +++ b/src/TabKeeper.UI.Wasm/_Imports.razor @@ -1,10 +1,16 @@ -@using System.Net.Http +@using System.Diagnostics.CodeAnalysis +@using System.Net.Http @using System.Net.Http.Json @using System.Reactive.Linq @using System.Reactive.Subjects @using Blazored.LocalStorage @using Core @using Core.Abstractions +@using Core.Blazor.Reactive.Forms +@using Core.Blazor.Reactive.Forms.Primitives +@using Core.Components.Forms; +@using Core.Reactive +@using Annular.Translate @using DynamicData @using DynamicData.Cache @using DynamicData.Aggregation @@ -16,13 +22,9 @@ @using Microsoft.JSInterop @using TabKeeper @using TabKeeper.Components -@using TabKeeper.Components.People -@using TabKeeper.Components.RxComponents -@using TabKeeper.People -@using TabKeeper.Tabs +@using TabKeeper.Common @using Ignis.Components @using Ignis.Components.HeadlessUI @using Ignis.Components.Reactivity @using Ignis.Utils -@using Core.Blazor.Components @using P41.FontAwesome \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/_usings.cs b/src/TabKeeper.UI.Wasm/_usings.cs index 07abfab..1121634 100644 --- a/src/TabKeeper.UI.Wasm/_usings.cs +++ b/src/TabKeeper.UI.Wasm/_usings.cs @@ -2,5 +2,10 @@ global using Core.Abstractions; global using DynamicData; global using DynamicData.Aggregation; +global using Flurl; +global using System.Reactive; global using System.Reactive.Linq; +global using System.Reactive.Threading; +global using System.Reactive.Threading.Tasks; global using TabKeeper; +global using TabKeeper.Layout; diff --git a/src/TabKeeper.UI.Wasm/assets/_buttons.scss b/src/TabKeeper.UI.Wasm/assets/_buttons.scss index 455edbf..084b76b 100644 --- a/src/TabKeeper.UI.Wasm/assets/_buttons.scss +++ b/src/TabKeeper.UI.Wasm/assets/_buttons.scss @@ -1,6 +1,6 @@ @layer components { .btn { - @apply px-3 py-1 flex items-center justify-center rounded-lg; + @apply px-3 py-1 flex items-center justify-center rounded-lg outline-none; } .btn-primary { @@ -11,6 +11,10 @@ @apply interactive-bg-secondary; } + .btn-tertiary { + @apply interactive-bg-tertiary; + } + .btn-danger { @apply interactive-bg-error; } diff --git a/src/TabKeeper.UI.Wasm/assets/_cards.scss b/src/TabKeeper.UI.Wasm/assets/_cards.scss index 1e2289d..3160c68 100644 --- a/src/TabKeeper.UI.Wasm/assets/_cards.scss +++ b/src/TabKeeper.UI.Wasm/assets/_cards.scss @@ -1,5 +1,5 @@ @layer components { .card { - @apply rounded-lg bg-surface-variant text-gray-500 p-4; + @apply rounded-lg bg-surface-variant p-4; } } diff --git a/src/TabKeeper.UI.Wasm/assets/_details.scss b/src/TabKeeper.UI.Wasm/assets/_details.scss new file mode 100644 index 0000000..9920aad --- /dev/null +++ b/src/TabKeeper.UI.Wasm/assets/_details.scss @@ -0,0 +1,47 @@ +@layer components { + details { + interpolate-size: allow-keywords; + overflow: clip; + margin-top: 0.125em; + border: 1px solid #dddddd; + background: #ffffff; + color: #333333; + border-radius: 3px; + + main { + padding: 4px; + } + + summary { + display: block; + cursor: pointer; + position: relative; + padding: 0.5em 0.5em 0.5em 0.7em; + background: #ededed; + color: #2b2b2b; + border-radius: 3px 3px 0 0; + } + } + + details:not([open]) summary:hover, + details:not([open]) summary:focus { + background: #f6f6f6; + color: #454545; + } + + details[open] summary { + outline: 1px solid #003eff; + background: #007fff; + color: #ffffff; + } + + details[open]::details-content { + height: auto; + } + + details::details-content { + height: 0; + overflow-y: clip; + transition: content-visibility 475ms allow-discrete, height 475ms; + } +} diff --git a/src/TabKeeper.UI.Wasm/assets/_icons.scss b/src/TabKeeper.UI.Wasm/assets/_icons.scss index f16b47d..219fa37 100644 --- a/src/TabKeeper.UI.Wasm/assets/_icons.scss +++ b/src/TabKeeper.UI.Wasm/assets/_icons.scss @@ -1,4 +1,7 @@ @layer base { + .icon-2xs { + @apply w-3 h-3; + } .icon-xs { @apply w-4 h-4; } @@ -14,4 +17,10 @@ .icon-xl { @apply w-8 h-8; } + .icon-2xl { + @apply w-9 h-9; + } + .icon-3xl { + @apply w-10 h-10; + } } diff --git a/src/TabKeeper.UI.Wasm/assets/_input.scss b/src/TabKeeper.UI.Wasm/assets/_input.scss deleted file mode 100644 index b4c53e2..0000000 --- a/src/TabKeeper.UI.Wasm/assets/_input.scss +++ /dev/null @@ -1,26 +0,0 @@ -@layer components { - /*input[type='checkbox'] { - @apply relative appearance-none min-w-[22px] min-h-[22px] m-1 bg-white border-2 rounded cursor-pointer outline-none;*/ - - /*&:checked { - @apply border-primary; - - &:before { - @apply absolute inset-0 flex items-center justify-center text-sm;*/ - /*content: url(../src/assets/images/icon-check.svg);*/ - /*} - }*/ - - /*&:focus:checked { - @apply border-2 border-primary; - } - - &:focus:not(:checked) { - @apply border-2 border-primary; - } - - &:disabled { - @apply cursor-default border-gray-500; - } - }*/ -} \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/assets/_material-input.scss b/src/TabKeeper.UI.Wasm/assets/_material-input.scss index 54b6d75..eaa1810 100644 --- a/src/TabKeeper.UI.Wasm/assets/_material-input.scss +++ b/src/TabKeeper.UI.Wasm/assets/_material-input.scss @@ -1,53 +1,43 @@ -@layer components { - .material-form { - @apply flex flex-col gap-4; +@layer base { + input, + textarea { + @apply w-full p-2 rounded focus:ring-0; + } - input { - @apply w-full placeholder:invisible rounded disabled:bg-gray-200 text-black; - } + .error, + .validation-message { + @apply text-sm text-error; + } - label { - @apply absolute top-0 left-2 px-2 text-sm transition-all ease-linear select-none pointer-events-none rounded; + .material-input { + @apply relative; - @apply peer-placeholder-shown:translate-y-1/2 peer-placeholder-shown:text-gray-500; + input { + @apply rounded p-2 pt-5 border border-transparent placeholder-transparent bg-surface focus:border-on-surface focus:ring-0; + + } - @apply -translate-y-1/2 text-gray-950 bg-transparent bg-white peer-disabled:bg-gray-200; - @apply peer-focus:-translate-y-1/2 peer-focus:text-gray-950; + input.invalid { + @apply border-error; } - .error { - @apply text-sm text-red-500; + label { + /* Defaults */ + @apply pointer-events-none absolute top-0 translate-y-1/2 text-on-surface cursor-text text-opacity-70 transition-all duration-200; + /* Styling */ + @apply text-sm font-medium; + @apply next-input-placeholder-shown:text-base; + @apply next-input-focus:text-sm; + /* Placing */ + @apply bottom-full px-2; + @apply next-input-placeholder-shown:bottom-1/2; + @apply next-input-focus:bottom-full next-input-focus:top-0; } + } + .material-checkbox { input[type='checkbox'] { @apply appearance-none min-w-[18px] min-h-[18px] rounded-sm; } } - - } - -/*.material-group { - @apply relative; - } - - .material-input { - @apply w-full placeholder:invisible rounded disabled:bg-gray-200 text-black; - } - - .material-label { - @apply absolute top-0 left-2 px-2 text-sm transition-all ease-linear select-none pointer-events-none rounded; - - @apply peer-placeholder-shown:translate-y-1/2 peer-placeholder-shown:text-gray-500; - - @apply -translate-y-1/2 text-gray-950 bg-transparent bg-white peer-disabled:bg-gray-200; - @apply peer-focus:-translate-y-1/2 peer-focus:text-gray-950; - } - - .material-error { - @apply text-sm text-red-500; - } - - input[type='checkbox'] { - @apply appearance-none min-w-[18px] min-h-[18px] rounded-sm; - }*/ \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/assets/_preferences.scss b/src/TabKeeper.UI.Wasm/assets/_preferences.scss new file mode 100644 index 0000000..1a76a70 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/assets/_preferences.scss @@ -0,0 +1,36 @@ +@layer components { + .preference-screen { + h1 { + @apply text-2xl text-on-surface font-semibold m-0; + } + } + + .preference-category { + @apply pb-4; + } + .preference-category-title-container { + @apply pb-2; + } + .preference-category-title-icon { + } + .preference-category-title { + } + .preference-category-description { + } + .preference-category-items { + } + + .preference-control-container { + @apply pb-3 last:pb-0; + } + + .preference-label { + @apply text-base text-on-surface; + } + .preference-input, + .preference-select { + @apply w-full rounded bg-primary px-2 py-1; + } + .preference-option { + } +} diff --git a/src/TabKeeper.UI.Wasm/assets/_skeleton.scss b/src/TabKeeper.UI.Wasm/assets/_skeleton.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/TabKeeper.UI.Wasm/assets/app.scss b/src/TabKeeper.UI.Wasm/assets/app.scss index 8229f6a..704db04 100644 --- a/src/TabKeeper.UI.Wasm/assets/app.scss +++ b/src/TabKeeper.UI.Wasm/assets/app.scss @@ -1,8 +1,10 @@ @import "./_buttons.scss"; @import "./_cards.scss"; +@import "./_details.scss"; @import "./_icons.scss"; -@import "./_input.scss"; @import "./_material-input.scss"; +@import "./_preferences.scss"; +@import "./_skeleton.scss"; @tailwind base; @tailwind components; @@ -20,69 +22,30 @@ } h1 { - @apply text-2xl font-bold mb-4; + @apply text-2xl font-bold; } + h2 { - @apply text-xl font-semibold mb-3; + @apply text-xl font-medium; } + h3 { - @apply text-lg font-medium mb-2; + @apply text-lg font-medium; } + h4 { - @apply text-base font-normal mb-1; + @apply text-base font-medium; } p { + @apply text-base; } small { + @apply text-xs; } - /*input[type='checkbox'] { - @apply relative appearance-none min-w-[22px] min-h-[22px] m-1 bg-white border-2 border-grey rounded cursor-pointer outline-none; - - &:checked { - @apply border-grey-130; - - &:before { - @apply absolute inset-0 flex items-center justify-center text-sm; - content: url(../src/assets/images/icon-check.svg); - } - } - - &:focus:checked { - @apply border-2 border-grey-130; - } - - &:focus:not(:checked) { - @apply border-2 border-grey; - } - - &:disabled { - @apply cursor-default border-grey; - } - }*/ -} - -@layer components { - .material-group { - @apply relative; - } - - .material-input { - @apply w-full placeholder:invisible rounded bg-white; - } - - .material-label { - @apply absolute top-0 left-2 px-2 text-sm transition-all ease-linear select-none pointer-events-none; - - @apply peer-placeholder-shown:translate-y-1/2 peer-placeholder-shown:text-gray-500; - - @apply -translate-y-1/2 bg-white text-gray-950; - @apply peer-focus:-translate-y-1/2 peer-focus:text-gray-950; - } - - .material-error { - @apply text-sm text-red-500; + label { + @apply text-base; } } diff --git a/src/TabKeeper.UI.Wasm/css.ps1 b/src/TabKeeper.UI.Wasm/css.ps1 index e1d3542..5f1d1de 100644 --- a/src/TabKeeper.UI.Wasm/css.ps1 +++ b/src/TabKeeper.UI.Wasm/css.ps1 @@ -1,16 +1,20 @@ [CmdletBinding()] param ( [switch] $watch = $false, - [switch] $publish = $false + [switch] $publish = $false, + [switch] $trace = $false ) $i = "./assets/app.scss" $o = "./wwwroot/css/app.min.css" $cmd = "tailwindcss", "-i $i", "-o $o", "--postcss" +# $cmd = "npx @tailwindcss/cli", "-i $i", "-o $o" if ($watch) { $cmd += "--watch" } elseif ($publish) { $cmd += "--minify" } +if ($trace) {$cmd += "--trace-warnings"} + $cmd = $cmd | Join-String -Separator ' ' Write-Host $cmd diff --git a/src/TabKeeper.UI.Wasm/package-lock.json b/src/TabKeeper.UI.Wasm/package-lock.json index 5529c61..5d2dfac 100644 --- a/src/TabKeeper.UI.Wasm/package-lock.json +++ b/src/TabKeeper.UI.Wasm/package-lock.json @@ -1,16 +1,19 @@ { - "name": "TabKeeper.UI.Wasm", + "name": "tabkeeper", "lockfileVersion": 3, "requires": true, "packages": { "": { + "name": "tabkeeper", "devDependencies": { "@tailwindcss/forms": "^0.5.7", "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e", "@tailwindcss/typography": "^0.5.12", "autoprefixer": "^10.4.19", "postcss": "^8.4.38", - "postcss-import": "^16.1.0" + "postcss-import": "^16.1.0", + "tailwind-material-colors": "3.0.2", + "tailwindcss": "^3.4.17" } }, "node_modules/@alloc/quick-lru": { @@ -18,7 +21,7 @@ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -31,7 +34,7 @@ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -45,11 +48,11 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -64,7 +67,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -74,35 +77,42 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@material/material-color-utilities": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.2.7.tgz", + "integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -116,7 +126,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -126,7 +136,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -140,22 +150,23 @@ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=14" } }, "node_modules/@tailwindcss/forms": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", - "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz", + "integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==", "dev": true, + "license": "MIT", "dependencies": { "mini-svg-data-uri": "^1.2.3" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" } }, "node_modules/@tailwindcss/nesting": { @@ -163,6 +174,7 @@ "resolved": "https://registry.npmjs.org/@tailwindcss/nesting/-/nesting-0.0.0-insiders.565cd3e.tgz", "integrity": "sha512-WhHoFBx19TnH/c+xLwT/sxei6+4RpdfiyG3MYXfmLaMsADmVqBkF7B6lDalgZD9YdM459MF7DtxVbWkOrV7IaQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-nested": "^5.0.5" }, @@ -171,10 +183,11 @@ } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.12.tgz", - "integrity": "sha512-CNwpBpconcP7ppxmuq3qvaCxiRWnbhANpY/ruH4L5qs2GCiVDJXde/pjj2HWPV1+Q4G9+V/etrwUYopdcjAlyg==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", + "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", "dev": true, + "license": "MIT", "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", @@ -182,28 +195,15 @@ "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders" - } - }, - "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -216,7 +216,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -229,14 +229,14 @@ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -250,12 +250,12 @@ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "dev": true, "funding": [ { @@ -271,12 +271,13 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -294,14 +295,14 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -314,28 +315,28 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -351,11 +352,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -369,15 +371,15 @@ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001610", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz", - "integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==", + "version": "1.0.30001692", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz", + "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==", "dev": true, "funding": [ { @@ -392,14 +394,15 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -424,7 +427,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -432,12 +435,26 @@ "node": ">= 6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -450,24 +467,35 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "peer": true + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -482,6 +510,7 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -494,56 +523,58 @@ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true, - "peer": true + "license": "Apache-2.0" }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.738", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.738.tgz", - "integrity": "sha512-lwKft2CLFztD+vEIpesrOtCrko/TFnEJlHFdRhazU7Y/jx5qc4cqsocfVrBg4So4gGe9lvxnbLIoev47WMpg+A==", - "dev": true + "version": "1.5.83", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.83.tgz", + "integrity": "sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -554,7 +585,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -563,21 +594,21 @@ } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -586,11 +617,11 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -607,6 +638,7 @@ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "dev": true, + "license": "MIT", "engines": { "node": "*" }, @@ -621,11 +653,11 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], - "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -635,29 +667,28 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -667,7 +698,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -680,6 +711,7 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -687,12 +719,19 @@ "node": ">= 0.4" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true, + "license": "MIT" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -701,12 +740,16 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -717,7 +760,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -727,7 +770,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -737,7 +780,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -750,7 +793,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -760,20 +803,17 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, - "peer": true + "license": "ISC" }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, - "peer": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -782,23 +822,26 @@ } }, "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, - "peer": true, + "license": "MIT", "bin": { "jiti": "bin/jiti.js" } }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, - "peer": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { @@ -806,54 +849,54 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/lodash.castarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "peer": true, - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -865,16 +908,17 @@ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", "dev": true, + "license": "MIT", "bin": { "mini-svg-data-uri": "cli.js" } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -886,11 +930,11 @@ } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "peer": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -900,7 +944,7 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -908,9 +952,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -918,6 +962,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -926,17 +971,18 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -946,6 +992,7 @@ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -955,7 +1002,7 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -965,17 +1012,24 @@ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">= 6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -984,37 +1038,39 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, - "peer": true, + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1027,6 +1083,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1036,15 +1093,15 @@ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "dev": true, "funding": [ { @@ -1060,10 +1117,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -1074,6 +1132,7 @@ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-16.1.0.tgz", "integrity": "sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -1091,7 +1150,7 @@ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" }, @@ -1121,7 +1180,7 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, + "license": "MIT", "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" @@ -1142,24 +1201,12 @@ } } }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/postcss-nested": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", "dev": true, + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.6" }, @@ -1175,10 +1222,11 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -1191,7 +1239,8 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -1212,13 +1261,14 @@ "url": "https://feross.org/support" } ], - "peer": true + "license": "MIT" }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^2.3.0" } @@ -1228,7 +1278,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -1237,18 +1287,22 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1258,7 +1312,7 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -1283,7 +1337,7 @@ "url": "https://feross.org/support" } ], - "peer": true, + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -1293,7 +1347,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -1306,7 +1360,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1316,7 +1370,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "peer": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -1324,11 +1378,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -1338,7 +1403,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1357,7 +1422,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1372,7 +1437,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1382,14 +1447,14 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1402,7 +1467,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1419,7 +1484,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1432,7 +1497,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1442,7 +1507,7 @@ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -1465,6 +1530,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1472,35 +1538,76 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwind-material-colors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tailwind-material-colors/-/tailwind-material-colors-3.0.2.tgz", + "integrity": "sha512-GAOfciMclkv9MdP2DY1JzLQwjBtTCltWZKK8NUuP0GT4Siy7LZ5TWL1cxvGwl/C1LC3XVcxpIZqcv98Je8I6hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@material/material-color-utilities": "^0.2.7", + "tailwind-material-surfaces": "^3.0.2", + "tailwind-mode-aware-colors": "^2.0.2" + }, + "peerDependencies": { + "tailwindcss": "^3.0.0" + } + }, + "node_modules/tailwind-material-surfaces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tailwind-material-surfaces/-/tailwind-material-surfaces-3.0.2.tgz", + "integrity": "sha512-ZElG3IPbSrFr2nzxQ++JvNYtJ2ffDfCc/9idAezXYznHrf9vpO0rV9gH1dPUVmXVSkhHerL34Boz14FGZ2H8uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tailwindcss-color-mix": "0.0.8" + }, + "peerDependencies": { + "tailwindcss": "^3.0.0" + } + }, + "node_modules/tailwind-mode-aware-colors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tailwind-mode-aware-colors/-/tailwind-mode-aware-colors-2.0.2.tgz", + "integrity": "sha512-ohgCFHWrGtT3PY3keun9LUDspt3+DFfaG4tA+MTjv8lCVLe0AxLSUrfAfr2eOcNP2c/V4KpB7qAmAsTJMHrfkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "color": "^4.2.3" + }, + "peerDependencies": { + "tailwindcss": "^3.4.1" + } + }, "node_modules/tailwindcss": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", - "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.0", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", @@ -1510,12 +1617,22 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss-color-mix": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/tailwindcss-color-mix/-/tailwindcss-color-mix-0.0.8.tgz", + "integrity": "sha512-agTN7BAA9eny2WABRX6jpHciQoBoSYGkZfLM1PpHAyNBPErQKFWUm1o1HjwNsZkilJL3hhUi2+H9MoCg+HT89A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "tailwindcss": "^3.0.0" + } + }, "node_modules/tailwindcss/node_modules/postcss-import": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -1529,31 +1646,51 @@ } }, "node_modules/tailwindcss/node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", "dev": true, - "peer": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.11" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -1563,7 +1700,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -1576,7 +1713,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -1589,12 +1726,12 @@ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true, - "peer": true + "license": "Apache-2.0" }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "dev": true, "funding": [ { @@ -1610,9 +1747,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -1625,14 +1763,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "peer": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -1648,7 +1787,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -1667,7 +1806,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1685,7 +1824,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1695,7 +1834,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1711,14 +1850,14 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "peer": true + "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1733,7 +1872,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1742,11 +1881,11 @@ } }, "node_modules/yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, - "peer": true, + "license": "ISC", "bin": { "yaml": "bin.mjs" }, diff --git a/src/TabKeeper.UI.Wasm/package.json b/src/TabKeeper.UI.Wasm/package.json index 2b4193b..8090cac 100644 --- a/src/TabKeeper.UI.Wasm/package.json +++ b/src/TabKeeper.UI.Wasm/package.json @@ -1,10 +1,14 @@ { + "name": "tabkeeper", + "author": "Panagiotis Athanasiou", "devDependencies": { "@tailwindcss/forms": "^0.5.7", "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e", "@tailwindcss/typography": "^0.5.12", "autoprefixer": "^10.4.19", "postcss": "^8.4.38", - "postcss-import": "^16.1.0" + "postcss-import": "^16.1.0", + "tailwind-material-colors": "3.0.2", + "tailwindcss": "^3.4.17" } -} \ No newline at end of file +} diff --git a/src/TabKeeper.UI.Wasm/tailwind-material-colors.esm.js b/src/TabKeeper.UI.Wasm/tailwind-material-colors.esm.js deleted file mode 100644 index bb28d70..0000000 --- a/src/TabKeeper.UI.Wasm/tailwind-material-colors.esm.js +++ /dev/null @@ -1,310 +0,0 @@ -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -function t(t){return t<0?-1:0===t?0:1}function r(t,r,e){return(1-e)*t+e*r}function e(t,r,e){return er?r:e}function n(t){return(t%=360)<0&&(t+=360),t}function a(t,r){return[t[0]*r[0][0]+t[1]*r[0][1]+t[2]*r[0][2],t[0]*r[1][0]+t[1]*r[1][1]+t[2]*r[1][2],t[0]*r[2][0]+t[1]*r[2][1]+t[2]*r[2][2]]} -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */const o=[[.41233895,.35762064,.18051042],[.2126,.7152,.0722],[.01932141,.11916382,.95034478]],i=[[3.2413774792388685,-1.5376652402851851,-.49885366846268053],[-.9691452513005321,1.8758853451067872,.04156585616912061],[.05562093689691305,-.20395524564742123,1.0571799111220335]],s=[95.047,100,108.883];function c(t,r,e){return(255<<24|(255&t)<<16|(255&r)<<8|255&e)>>>0}function l(t){return c(m(t[0]),m(t[1]),m(t[2]))}function u(t){return t>>16&255}function f(t){return t>>8&255}function h(t){return 255&t}function d(t){const r=function(t){return a([b(u(t)),b(f(t)),b(h(t))],o)}(t)[1];return 116*v(r/100)-16}function p(t){return 100*function(t){const r=24389/27,e=t*t*t;return e>216/24389?e:(116*t-16)/r} -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */((t+16)/116)}function g(t){return 116*v(t/100)-16}function b(t){const r=t/255;return r<=.040449936?r/12.92*100:100*Math.pow((r+.055)/1.055,2.4)}function m(t){const r=t/100;let e=0;return e=r<=.0031308?12.92*r:1.055*Math.pow(r,1/2.4)-.055,n=0,a=255,(o=Math.round(255*e))a?a:o;var n,a,o}function v(t){return t>216/24389?Math.pow(t,1/3):(903.2962962962963*t+16)/116}class y{static make(t=function(){return s}(),e=200/Math.PI*p(50)/100,n=50,a=2,o=!1){const i=t,c=.401288*i[0]+.650173*i[1]+-.051461*i[2],l=-.250268*i[0]+1.204414*i[1]+.045854*i[2],u=-.002079*i[0]+.048952*i[1]+.953127*i[2],f=.8+a/10,h=f>=.9?r(.59,.69,10*(f-.9)):r(.525,.59,10*(f-.8));let d=o?1:f*(1-1/3.6*Math.exp((-e-42)/92));d=d>1?1:d<0?0:d;const g=f,b=[d*(100/c)+1-d,d*(100/l)+1-d,d*(100/u)+1-d],m=1/(5*e+1),v=m*m*m*m,k=1-v,w=v*e+.1*k*k*Math.cbrt(5*e),M=p(n)/t[1],C=1.48+Math.sqrt(M),P=.725/Math.pow(M,.2),x=P,_=[Math.pow(w*b[0]*c/100,.42),Math.pow(w*b[1]*l/100,.42),Math.pow(w*b[2]*u/100,.42)],D=[400*_[0]/(_[0]+27.13),400*_[1]/(_[1]+27.13),400*_[2]/(_[2]+27.13)];return new y(M,(2*D[0]+D[1]+.05*D[2])*P,P,x,h,g,b,w,Math.pow(w,.25),C)}constructor(t,r,e,n,a,o,i,s,c,l){this.n=t,this.aw=r,this.nbb=e,this.ncb=n,this.c=a,this.nc=o,this.rgbD=i,this.fl=s,this.fLRoot=c,this.z=l}}y.DEFAULT=y.make(); -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -class k{constructor(t,r,e,n,a,o,i,s,c){this.hue=t,this.chroma=r,this.j=e,this.q=n,this.m=a,this.s=o,this.jstar=i,this.astar=s,this.bstar=c}distance(t){const r=this.jstar-t.jstar,e=this.astar-t.astar,n=this.bstar-t.bstar,a=Math.sqrt(r*r+e*e+n*n);return 1.41*Math.pow(a,.63)}static fromInt(t){return k.fromIntInViewingConditions(t,y.DEFAULT)}static fromIntInViewingConditions(r,e){const n=(65280&r)>>8,a=255&r,o=b((16711680&r)>>16),i=b(n),s=b(a),c=.41233895*o+.35762064*i+.18051042*s,l=.2126*o+.7152*i+.0722*s,u=.01932141*o+.11916382*i+.95034478*s,f=.401288*c+.650173*l-.051461*u,h=-.250268*c+1.204414*l+.045854*u,d=-.002079*c+.048952*l+.953127*u,p=e.rgbD[0]*f,g=e.rgbD[1]*h,m=e.rgbD[2]*d,v=Math.pow(e.fl*Math.abs(p)/100,.42),y=Math.pow(e.fl*Math.abs(g)/100,.42),w=Math.pow(e.fl*Math.abs(m)/100,.42),M=400*t(p)*v/(v+27.13),C=400*t(g)*y/(y+27.13),P=400*t(m)*w/(w+27.13),x=(11*M+-12*C+P)/11,_=(M+C-2*P)/9,D=(20*M+20*C+21*P)/20,O=(40*M+20*C+P)/20,I=180*Math.atan2(_,x)/Math.PI,F=I<0?I+360:I>=360?I-360:I,A=F*Math.PI/180,S=O*e.nbb,N=100*Math.pow(S/e.aw,e.c*e.z),T=4/e.c*Math.sqrt(N/100)*(e.aw+4)*e.fLRoot,E=F<20.14?F+360:F,B=5e4/13*(.25*(Math.cos(E*Math.PI/180+2)+3.8))*e.nc*e.ncb*Math.sqrt(x*x+_*_)/(D+.305),L=Math.pow(B,.9)*Math.pow(1.64-Math.pow(.29,e.n),.73),j=L*Math.sqrt(N/100),R=j*e.fLRoot,$=50*Math.sqrt(L*e.c/(e.aw+4)),V=(1+100*.007)*N/(1+.007*N),q=1/.0228*Math.log(1+.0228*R),z=q*Math.cos(A),U=q*Math.sin(A);return new k(F,j,N,T,R,$,V,z,U)}static fromJch(t,r,e){return k.fromJchInViewingConditions(t,r,e,y.DEFAULT)}static fromJchInViewingConditions(t,r,e,n){const a=4/n.c*Math.sqrt(t/100)*(n.aw+4)*n.fLRoot,o=r*n.fLRoot,i=r/Math.sqrt(t/100),s=50*Math.sqrt(i*n.c/(n.aw+4)),c=e*Math.PI/180,l=(1+100*.007)*t/(1+.007*t),u=1/.0228*Math.log(1+.0228*o),f=u*Math.cos(c),h=u*Math.sin(c);return new k(e,r,t,a,o,s,l,f,h)}static fromUcs(t,r,e){return k.fromUcsInViewingConditions(t,r,e,y.DEFAULT)}static fromUcsInViewingConditions(t,r,e,n){const a=r,o=e,i=Math.sqrt(a*a+o*o),s=(Math.exp(.0228*i)-1)/.0228/n.fLRoot;let c=Math.atan2(o,a)*(180/Math.PI);c<0&&(c+=360);const l=t/(1-.007*(t-100));return k.fromJchInViewingConditions(l,s,c,n)}toInt(){return this.viewed(y.DEFAULT)}viewed(r){const e=0===this.chroma||0===this.j?0:this.chroma/Math.sqrt(this.j/100),n=Math.pow(e/Math.pow(1.64-Math.pow(.29,r.n),.73),1/.9),a=this.hue*Math.PI/180,o=.25*(Math.cos(a+2)+3.8),s=r.aw*Math.pow(this.j/100,1/r.c/r.z),l=o*(5e4/13)*r.nc*r.ncb,u=s/r.nbb,f=Math.sin(a),h=Math.cos(a),d=23*(u+.305)*n/(23*l+11*n*h+108*n*f),p=d*h,g=d*f,b=(460*u+451*p+288*g)/1403,v=(460*u-891*p-261*g)/1403,y=(460*u-220*p-6300*g)/1403,k=Math.max(0,27.13*Math.abs(b)/(400-Math.abs(b))),w=t(b)*(100/r.fl)*Math.pow(k,1/.42),M=Math.max(0,27.13*Math.abs(v)/(400-Math.abs(v))),C=t(v)*(100/r.fl)*Math.pow(M,1/.42),P=Math.max(0,27.13*Math.abs(y)/(400-Math.abs(y))),x=t(y)*(100/r.fl)*Math.pow(P,1/.42),_=w/r.rgbD[0],D=C/r.rgbD[1],O=x/r.rgbD[2],I=function(t,r,e){const n=i,a=n[0][0]*t+n[0][1]*r+n[0][2]*e,o=n[1][0]*t+n[1][1]*r+n[1][2]*e,s=n[2][0]*t+n[2][1]*r+n[2][2]*e;return c(m(a),m(o),m(s))}(1.86206786*_-1.01125463*D+.14918677*O,.38752654*_+.62144744*D-.00897398*O,-.0158415*_-.03412294*D+1.04996444*O);return I}static fromXyzInViewingConditions(r,e,n,a){const o=.401288*r+.650173*e-.051461*n,i=-.250268*r+1.204414*e+.045854*n,s=-.002079*r+.048952*e+.953127*n,c=a.rgbD[0]*o,l=a.rgbD[1]*i,u=a.rgbD[2]*s,f=Math.pow(a.fl*Math.abs(c)/100,.42),h=Math.pow(a.fl*Math.abs(l)/100,.42),d=Math.pow(a.fl*Math.abs(u)/100,.42),p=400*t(c)*f/(f+27.13),g=400*t(l)*h/(h+27.13),b=400*t(u)*d/(d+27.13),m=(11*p+-12*g+b)/11,v=(p+g-2*b)/9,y=(20*p+20*g+21*b)/20,w=(40*p+20*g+b)/20,M=180*Math.atan2(v,m)/Math.PI,C=M<0?M+360:M>=360?M-360:M,P=C*Math.PI/180,x=w*a.nbb,_=100*Math.pow(x/a.aw,a.c*a.z),D=4/a.c*Math.sqrt(_/100)*(a.aw+4)*a.fLRoot,O=C<20.14?C+360:C,I=5e4/13*(1/4*(Math.cos(O*Math.PI/180+2)+3.8))*a.nc*a.ncb*Math.sqrt(m*m+v*v)/(y+.305),F=Math.pow(I,.9)*Math.pow(1.64-Math.pow(.29,a.n),.73),A=F*Math.sqrt(_/100),S=A*a.fLRoot,N=50*Math.sqrt(F*a.c/(a.aw+4)),T=(1+100*.007)*_/(1+.007*_),E=Math.log(1+.0228*S)/.0228,B=E*Math.cos(P),L=E*Math.sin(P);return new k(C,A,_,D,S,N,T,B,L)}xyzInViewingConditions(r){const e=0===this.chroma||0===this.j?0:this.chroma/Math.sqrt(this.j/100),n=Math.pow(e/Math.pow(1.64-Math.pow(.29,r.n),.73),1/.9),a=this.hue*Math.PI/180,o=.25*(Math.cos(a+2)+3.8),i=r.aw*Math.pow(this.j/100,1/r.c/r.z),s=o*(5e4/13)*r.nc*r.ncb,c=i/r.nbb,l=Math.sin(a),u=Math.cos(a),f=23*(c+.305)*n/(23*s+11*n*u+108*n*l),h=f*u,d=f*l,p=(460*c+451*h+288*d)/1403,g=(460*c-891*h-261*d)/1403,b=(460*c-220*h-6300*d)/1403,m=Math.max(0,27.13*Math.abs(p)/(400-Math.abs(p))),v=t(p)*(100/r.fl)*Math.pow(m,1/.42),y=Math.max(0,27.13*Math.abs(g)/(400-Math.abs(g))),k=t(g)*(100/r.fl)*Math.pow(y,1/.42),w=Math.max(0,27.13*Math.abs(b)/(400-Math.abs(b))),M=t(b)*(100/r.fl)*Math.pow(w,1/.42),C=v/r.rgbD[0],P=k/r.rgbD[1],x=M/r.rgbD[2];return[1.86206786*C-1.01125463*P+.14918677*x,.38752654*C+.62144744*P-.00897398*x,-.0158415*C-.03412294*P+1.04996444*x]}} -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */class w{static sanitizeRadians(t){return(t+8*Math.PI)%(2*Math.PI)}static trueDelinearized(t){const r=t/100;let e=0;return e=r<=.0031308?12.92*r:1.055*Math.pow(r,1/2.4)-.055,255*e}static chromaticAdaptation(r){const e=Math.pow(Math.abs(r),.42);return 400*t(r)*e/(e+27.13)}static hueOf(t){const r=a(t,w.SCALED_DISCOUNT_FROM_LINRGB),e=w.chromaticAdaptation(r[0]),n=w.chromaticAdaptation(r[1]),o=w.chromaticAdaptation(r[2]),i=(11*e+-12*n+o)/11,s=(e+n-2*o)/9;return Math.atan2(s,i)}static areInCyclicOrder(t,r,e){return w.sanitizeRadians(r-t)100.01||M[1]>100.01||M[2]>100.01?0:l(M);n-=(_-e)*n/(2*_)}return 0}static solveToInt(t,r,e){if(r<1e-4||e<1e-4||e>99.9999)return function(t){const r=m(p(t));return c(r,r,r)}(e);const a=(t=n(t))/180*Math.PI,o=p(e),i=w.findResultByJ(a,r,o);if(0!==i)return i;return l(w.bisectToLimit(o,a))}static solveToCam(t,r,e){return k.fromInt(w.solveToInt(t,r,e))}}w.SCALED_DISCOUNT_FROM_LINRGB=[[.001200833568784504,.002389694492170889,.0002795742885861124],[.0005891086651375999,.0029785502573438758,.0003270666104008398],[.00010146692491640572,.0005364214359186694,.0032979401770712076]],w.LINRGB_FROM_SCALED_DISCOUNT=[[1373.2198709594231,-1100.4251190754821,-7.278681089101213],[-271.815969077903,559.6580465940733,-32.46047482791194],[1.9622899599665666,-57.173814538844006,308.7233197812385]],w.Y_FROM_LINRGB=[.2126,.7152,.0722],w.CRITICAL_PLANES=[.015176349177441876,.045529047532325624,.07588174588720938,.10623444424209313,.13658714259697685,.16693984095186062,.19729253930674434,.2276452376616281,.2579979360165119,.28835063437139563,.3188300904430532,.350925934958123,.3848314933096426,.42057480301049466,.458183274052838,.4976837250274023,.5391024159806381,.5824650784040898,.6277969426914107,.6751227633498623,.7244668422128921,.775853049866786,.829304845476233,.8848452951698498,.942497089126609,1.0022825574869039,1.0642236851973577,1.1283421258858297,1.1946592148522128,1.2631959812511864,1.3339731595349034,1.407011200216447,1.4823302800086415,1.5599503113873272,1.6398909516233677,1.7221716113234105,1.8068114625156377,1.8938294463134073,1.9832442801866852,2.075074464868551,2.1693382909216234,2.2660538449872063,2.36523901573795,2.4669114995532007,2.5710888059345764,2.6777882626779785,2.7870270208169257,2.898822059350997,3.0131901897720907,3.1301480604002863,3.2497121605402226,3.3718988244681087,3.4967242352587946,3.624204428461639,3.754355295633311,3.887192587735158,4.022731918402185,4.160988767090289,4.301978482107941,4.445716283538092,4.592217266055746,4.741496401646282,4.893568542229298,5.048448422192488,5.20615066083972,5.3666897647573375,5.5300801301023865,5.696336044816294,5.865471690767354,6.037501145825082,6.212438385869475,6.390297286737924,6.571091626112461,6.7548350853498045,6.941541251256611,7.131223617812143,7.323895587840543,7.5195704746346665,7.7182615035334345,7.919981813454504,8.124744458384042,8.332562408825165,8.543448553206703,8.757415699253682,8.974476575321063,9.194643831691977,9.417930041841839,9.644347703669503,9.873909240696694,10.106627003236781,10.342513269534024,10.58158024687427,10.8238400726681,11.069304815507364,11.317986476196008,11.569896988756009,11.825048221409341,12.083451977536606,12.345119996613247,12.610063955123938,12.878295467455942,13.149826086772048,13.42466730586372,13.702830557985108,13.984327217668513,14.269168601521828,14.55736596900856,14.848930523210871,15.143873411576273,15.44220572664832,15.743938506781891,16.04908273684337,16.35764934889634,16.66964922287304,16.985093187232053,17.30399201960269,17.62635644741625,17.95219714852476,18.281524751807332,18.614349837764564,18.95068293910138,19.290534541298456,19.633915083172692,19.98083495742689,20.331304511189067,20.685334046541502,21.042933821039977,21.404114048223256,21.76888489811322,22.137256497705877,22.50923893145328,22.884842241736916,23.264076429332462,23.6469514538663,24.033477234264016,24.42366364919083,24.817520537484558,25.21505769858089,25.61628489293138,26.021211842414342,26.429848230738664,26.842203703840827,27.258287870275353,27.678110301598522,28.10168053274597,28.529008062403893,28.96010235337422,29.39497283293396,29.83362889318845,30.276079891419332,30.722335150426627,31.172403958865512,31.62629557157785,32.08401920991837,32.54558406207592,33.010999283389665,33.4802739966603,33.953417292456834,34.430438229418264,34.911345834551085,35.39614910352207,35.88485700094671,36.37747846067349,36.87402238606382,37.37449765026789,37.87891309649659,38.38727753828926,38.89959975977785,39.41588851594697,39.93615253289054,40.460400508064545,40.98864111053629,41.520882981230194,42.05713473317016,42.597404951718396,43.141702194811224,43.6900349931913,44.24241185063697,44.798841244188324,45.35933162437017,45.92389141541209,46.49252901546552,47.065252796817916,47.64207110610409,48.22299226451468,48.808024568002054,49.3971762874833,49.9904556690408,50.587870934119984,51.189430279724725,51.79514187861014,52.40501387947288,53.0190544071392,53.637271562750364,54.259673423945976,54.88626804504493,55.517063457223934,56.15206766869424,56.79128866487574,57.43473440856916,58.08241284012621,58.734331877617365,59.39049941699807,60.05092333227251,60.715611475655585,61.38457167773311,62.057811747619894,62.7353394731159,63.417162620860914,64.10328893648692,64.79372614476921,65.48848194977529,66.18756403501224,66.89098006357258,67.59873767827808,68.31084450182222,69.02730813691093,69.74813616640164,70.47333615344107,71.20291564160104,71.93688215501312,72.67524319850172,73.41800625771542,74.16517879925733,74.9167682708136,75.67278210128072,76.43322770089146,77.1981124613393,77.96744375590167,78.74122893956174,79.51947534912904,80.30219030335869,81.08938110306934,81.88105503125999,82.67721935322541,83.4778813166706,84.28304815182372,85.09272707154808,85.90692527145302,86.72564993000343,87.54890820862819,88.3767072518277,89.2090541872801,90.04595612594655,90.88742016217518,91.73345337380438,92.58406282226491,93.43925555268066,94.29903859396902,95.16341895893969,96.03240364439274,96.9059996312159,97.78421388448044,98.6670533535366,99.55452497210776]; -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -class M{static from(t,r,e){return new M(w.solveToInt(t,r,e))}static fromInt(t){return new M(t)}toInt(){return this.argb}get hue(){return this.internalHue}set hue(t){this.setInternalState(w.solveToInt(t,this.internalChroma,this.internalTone))}get chroma(){return this.internalChroma}set chroma(t){this.setInternalState(w.solveToInt(this.internalHue,t,this.internalTone))}get tone(){return this.internalTone}set tone(t){this.setInternalState(w.solveToInt(this.internalHue,this.internalChroma,t))}constructor(t){this.argb=t;const r=k.fromInt(t);this.internalHue=r.hue,this.internalChroma=r.chroma,this.internalTone=d(t),this.argb=t}setInternalState(t){const r=k.fromInt(t);this.internalHue=r.hue,this.internalChroma=r.chroma,this.internalTone=d(t),this.argb=t}inViewingConditions(t){const r=k.fromInt(this.toInt()).xyzInViewingConditions(t),e=k.fromXyzInViewingConditions(r[0],r[1],r[2],y.make());return M.from(e.hue,e.chroma,g(r[1]))}} -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */class C{static harmonize(t,r){const e=M.fromInt(t),a=M.fromInt(r),o=(i=e.hue,s=a.hue,180-Math.abs(Math.abs(i-s)-180));var i,s;const c=Math.min(.5*o,15),l=n(e.hue+c*(u=e.hue,n(a.hue-u)<=180?1:-1));var u;return M.from(l,e.chroma,e.tone).toInt()}static hctHue(t,r,e){const n=C.cam16Ucs(t,r,e),a=k.fromInt(n),o=k.fromInt(t);return M.from(a.hue,o.chroma,d(t)).toInt()}static cam16Ucs(t,r,e){const n=k.fromInt(t),a=k.fromInt(r),o=n.jstar,i=n.astar,s=n.bstar,c=o+(a.jstar-o)*e,l=i+(a.astar-i)*e,u=s+(a.bstar-s)*e;return k.fromUcs(c,l,u).toInt()}} -/** - * @license - * Copyright 2022 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */class P{static ratioOfTones(t,r){return t=e(0,100,t),r=e(0,100,r),P.ratioOfYs(p(t),p(r))}static ratioOfYs(t,r){const e=t>r?t:r;return(e+5)/((e===r?t:r)+5)}static lighter(t,r){if(t<0||t>100)return-1;const e=p(t),n=r*(e+5)-5,a=P.ratioOfYs(n,e),o=Math.abs(a-r);if(a.04)return-1;const i=g(n)+.4;return i<0||i>100?-1:i}static darker(t,r){if(t<0||t>100)return-1;const e=p(t),n=(e+5)/r-5,a=P.ratioOfYs(e,n),o=Math.abs(a-r);if(a.04)return-1;const i=g(n)-.4;return i<0||i>100?-1:i}static lighterUnsafe(t,r){const e=P.lighter(t,r);return e<0?100:e}static darkerUnsafe(t,r){const e=P.darker(t,r);return e<0?0:e}} -/** - * @license - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */class x{static isDisliked(t){const r=Math.round(t.hue)>=90&&Math.round(t.hue)<=111,e=Math.round(t.chroma)>16,n=Math.round(t.tone)<65;return r&&e&&n}static fixIfDisliked(t){return x.isDisliked(t)?M.from(t.hue,t.chroma,70):t}} -/** - * @license - * Copyright 2022 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */class _{static fromPalette(t){return new _(t.name??"",t.palette,t.tone,t.isBackground??!1,t.background,t.secondBackground,t.contrastCurve,t.toneDeltaPair)}constructor(t,r,e,n,a,o,i,s){if(this.name=t,this.palette=r,this.tone=e,this.isBackground=n,this.background=a,this.secondBackground=o,this.contrastCurve=i,this.toneDeltaPair=s,this.hctCache=new Map,!a&&o)throw new Error(`Color ${t} has secondBackgrounddefined, but background is not defined.`);if(!a&&i)throw new Error(`Color ${t} has contrastCurvedefined, but background is not defined.`);if(a&&!i)throw new Error(`Color ${t} has backgrounddefined, but contrastCurve is not defined.`)}getArgb(t){return this.getHct(t).toInt()}getHct(t){const r=this.hctCache.get(t);if(null!=r)return r;const e=this.getTone(t),n=this.palette(t).getHct(e);return this.hctCache.size>4&&this.hctCache.clear(),this.hctCache.set(t,n),n}getTone(t){const r=t.contrastLevel<0;if(this.toneDeltaPair){const n=this.toneDeltaPair(t),a=n.roleA,o=n.roleB,i=n.delta,s=n.polarity,c=n.stayTogether,l=this.background(t).getTone(t),u="nearer"===s||"lighter"===s&&!t.isDark||"darker"===s&&t.isDark,f=u?a:o,h=u?o:a,d=this.name===f.name,p=t.isDark?1:-1,g=f.contrastCurve.getContrast(t.contrastLevel),b=h.contrastCurve.getContrast(t.contrastLevel),m=f.tone(t);let v=P.ratioOfTones(l,m)>=g?m:_.foregroundTone(l,g);const y=h.tone(t);let k=P.ratioOfTones(l,y)>=b?y:_.foregroundTone(l,b);return r&&(v=_.foregroundTone(l,g),k=_.foregroundTone(l,b)),(k-v)*p>=i||(k=e(0,100,v+i*p),(k-v)*p>=i||(v=e(0,100,k-i*p))),50<=v&&v<60?p>0?(v=60,k=Math.max(k,v+i*p)):(v=49,k=Math.min(k,v+i*p)):50<=k&&k<60&&(c?p>0?(v=60,k=Math.max(k,v+i*p)):(v=49,k=Math.min(k,v+i*p)):k=p>0?60:49),d?v:k}{let e=this.tone(t);if(null==this.background)return e;const n=this.background(t).getTone(t),a=this.contrastCurve.getContrast(t.contrastLevel);if(P.ratioOfTones(n,e)>=a||(e=_.foregroundTone(n,a)),r&&(e=_.foregroundTone(n,a)),this.isBackground&&50<=e&&e<60&&(e=P.ratioOfTones(49,n)>=a?49:60),this.secondBackground){const[r,n]=[this.background,this.secondBackground],[o,i]=[r(t).getTone(t),n(t).getTone(t)],[s,c]=[Math.max(o,i),Math.min(o,i)];if(P.ratioOfTones(s,e)>=a&&P.ratioOfTones(c,e)>=a)return e;const l=P.lighter(s,a),u=P.darker(c,a),f=[];-1!==l&&f.push(l),-1!==u&&f.push(u);return _.tonePrefersLightForeground(o)||_.tonePrefersLightForeground(i)?l<0?100:l:1===f.length?f[0]:u<0?0:u}return e}}static foregroundTone(t,r){const e=P.lighterUnsafe(t,r),n=P.darkerUnsafe(t,r),a=P.ratioOfTones(e,t),o=P.ratioOfTones(n,t);if(_.tonePrefersLightForeground(t)){const t=Math.abs(a-o)<.1&&a=r||a>=o||t?e:n}return o>=r||o>=a?n:e}static tonePrefersLightForeground(t){return Math.round(t)<60}static toneAllowsLightForeground(t){return Math.round(t)<=49}static enableLightForeground(t){return _.tonePrefersLightForeground(t)&&!_.toneAllowsLightForeground(t)?49:t}} -/** - * @license - * Copyright 2022 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */var D;!function(t){t[t.MONOCHROME=0]="MONOCHROME",t[t.NEUTRAL=1]="NEUTRAL",t[t.TONAL_SPOT=2]="TONAL_SPOT",t[t.VIBRANT=3]="VIBRANT",t[t.EXPRESSIVE=4]="EXPRESSIVE",t[t.FIDELITY=5]="FIDELITY",t[t.CONTENT=6]="CONTENT",t[t.RAINBOW=7]="RAINBOW",t[t.FRUIT_SALAD=8]="FRUIT_SALAD"}(D||(D={})); -/** - * @license - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -class O{constructor(t,r,e,n){this.low=t,this.normal=r,this.medium=e,this.high=n}getContrast(t){return t<=-1?this.low:t<0?r(this.low,this.normal,(t- -1)/1):t<.5?r(this.normal,this.medium,(t-0)/.5):t<1?r(this.medium,this.high,(t-.5)/.5):this.high}} -/** - * @license - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */class I{constructor(t,r,e,n,a){this.roleA=t,this.roleB=r,this.delta=e,this.polarity=n,this.stayTogether=a}} -/** - * @license - * Copyright 2022 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */function F(t){return t.variant===D.FIDELITY||t.variant===D.CONTENT}function A(t){return t.variant===D.MONOCHROME}function S(t,r){const e=t.inViewingConditions(function(t){return y.make(void 0,void 0,t.isDark?30:80,void 0,void 0)}(r));return _.tonePrefersLightForeground(t.tone)&&!_.toneAllowsLightForeground(e.tone)?_.enableLightForeground(t.tone):_.enableLightForeground(e.tone)}class N{static highestSurface(t){return t.isDark?N.surfaceBright:N.surfaceDim}}N.contentAccentToneDelta=15,N.primaryPaletteKeyColor=_.fromPalette({name:"primary_palette_key_color",palette:t=>t.primaryPalette,tone:t=>t.primaryPalette.keyColor.tone}),N.secondaryPaletteKeyColor=_.fromPalette({name:"secondary_palette_key_color",palette:t=>t.secondaryPalette,tone:t=>t.secondaryPalette.keyColor.tone}),N.tertiaryPaletteKeyColor=_.fromPalette({name:"tertiary_palette_key_color",palette:t=>t.tertiaryPalette,tone:t=>t.tertiaryPalette.keyColor.tone}),N.neutralPaletteKeyColor=_.fromPalette({name:"neutral_palette_key_color",palette:t=>t.neutralPalette,tone:t=>t.neutralPalette.keyColor.tone}),N.neutralVariantPaletteKeyColor=_.fromPalette({name:"neutral_variant_palette_key_color",palette:t=>t.neutralVariantPalette,tone:t=>t.neutralVariantPalette.keyColor.tone}),N.background=_.fromPalette({name:"background",palette:t=>t.neutralPalette,tone:t=>t.isDark?6:98,isBackground:!0}),N.onBackground=_.fromPalette({name:"on_background",palette:t=>t.neutralPalette,tone:t=>t.isDark?90:10,background:t=>N.background,contrastCurve:new O(3,3,4.5,7)}),N.surface=_.fromPalette({name:"surface",palette:t=>t.neutralPalette,tone:t=>t.isDark?6:98,isBackground:!0}),N.surfaceDim=_.fromPalette({name:"surface_dim",palette:t=>t.neutralPalette,tone:t=>t.isDark?6:87,isBackground:!0}),N.surfaceBright=_.fromPalette({name:"surface_bright",palette:t=>t.neutralPalette,tone:t=>t.isDark?24:98,isBackground:!0}),N.surfaceContainerLowest=_.fromPalette({name:"surface_container_lowest",palette:t=>t.neutralPalette,tone:t=>t.isDark?4:100,isBackground:!0}),N.surfaceContainerLow=_.fromPalette({name:"surface_container_low",palette:t=>t.neutralPalette,tone:t=>t.isDark?10:96,isBackground:!0}),N.surfaceContainer=_.fromPalette({name:"surface_container",palette:t=>t.neutralPalette,tone:t=>t.isDark?12:94,isBackground:!0}),N.surfaceContainerHigh=_.fromPalette({name:"surface_container_high",palette:t=>t.neutralPalette,tone:t=>t.isDark?17:92,isBackground:!0}),N.surfaceContainerHighest=_.fromPalette({name:"surface_container_highest",palette:t=>t.neutralPalette,tone:t=>t.isDark?22:90,isBackground:!0}),N.onSurface=_.fromPalette({name:"on_surface",palette:t=>t.neutralPalette,tone:t=>t.isDark?90:10,background:t=>N.highestSurface(t),contrastCurve:new O(4.5,7,11,21)}),N.surfaceVariant=_.fromPalette({name:"surface_variant",palette:t=>t.neutralVariantPalette,tone:t=>t.isDark?30:90,isBackground:!0}),N.onSurfaceVariant=_.fromPalette({name:"on_surface_variant",palette:t=>t.neutralVariantPalette,tone:t=>t.isDark?80:30,background:t=>N.highestSurface(t),contrastCurve:new O(3,4.5,7,11)}),N.inverseSurface=_.fromPalette({name:"inverse_surface",palette:t=>t.neutralPalette,tone:t=>t.isDark?90:20}),N.inverseOnSurface=_.fromPalette({name:"inverse_on_surface",palette:t=>t.neutralPalette,tone:t=>t.isDark?20:95,background:t=>N.inverseSurface,contrastCurve:new O(4.5,7,11,21)}),N.outline=_.fromPalette({name:"outline",palette:t=>t.neutralVariantPalette,tone:t=>t.isDark?60:50,background:t=>N.highestSurface(t),contrastCurve:new O(1.5,3,4.5,7)}),N.outlineVariant=_.fromPalette({name:"outline_variant",palette:t=>t.neutralVariantPalette,tone:t=>t.isDark?30:80,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7)}),N.shadow=_.fromPalette({name:"shadow",palette:t=>t.neutralPalette,tone:t=>0}),N.scrim=_.fromPalette({name:"scrim",palette:t=>t.neutralPalette,tone:t=>0}),N.surfaceTint=_.fromPalette({name:"surface_tint",palette:t=>t.primaryPalette,tone:t=>t.isDark?80:40,isBackground:!0}),N.primary=_.fromPalette({name:"primary",palette:t=>t.primaryPalette,tone:t=>A(t)?t.isDark?100:0:t.isDark?80:40,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(3,4.5,7,11),toneDeltaPair:t=>new I(N.primaryContainer,N.primary,15,"nearer",!1)}),N.onPrimary=_.fromPalette({name:"on_primary",palette:t=>t.primaryPalette,tone:t=>A(t)?t.isDark?10:90:t.isDark?20:100,background:t=>N.primary,contrastCurve:new O(4.5,7,11,21)}),N.primaryContainer=_.fromPalette({name:"primary_container",palette:t=>t.primaryPalette,tone:t=>F(t)?S(t.sourceColorHct,t):A(t)?t.isDark?85:25:t.isDark?30:90,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.primaryContainer,N.primary,15,"nearer",!1)}),N.onPrimaryContainer=_.fromPalette({name:"on_primary_container",palette:t=>t.primaryPalette,tone:t=>F(t)?_.foregroundTone(N.primaryContainer.tone(t),4.5):A(t)?t.isDark?0:100:t.isDark?90:10,background:t=>N.primaryContainer,contrastCurve:new O(4.5,7,11,21)}),N.inversePrimary=_.fromPalette({name:"inverse_primary",palette:t=>t.primaryPalette,tone:t=>t.isDark?40:80,background:t=>N.inverseSurface,contrastCurve:new O(3,4.5,7,11)}),N.secondary=_.fromPalette({name:"secondary",palette:t=>t.secondaryPalette,tone:t=>t.isDark?80:40,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(3,4.5,7,11),toneDeltaPair:t=>new I(N.secondaryContainer,N.secondary,15,"nearer",!1)}),N.onSecondary=_.fromPalette({name:"on_secondary",palette:t=>t.secondaryPalette,tone:t=>A(t)?t.isDark?10:100:t.isDark?20:100,background:t=>N.secondary,contrastCurve:new O(4.5,7,11,21)}),N.secondaryContainer=_.fromPalette({name:"secondary_container",palette:t=>t.secondaryPalette,tone:t=>{const r=t.isDark?30:90;if(A(t))return t.isDark?30:85;if(!F(t))return r;let e=function(t,r,e,n){let a=e,o=M.from(t,r,e);if(o.chromai.chroma)break;if(Math.abs(i.chroma-r)<.4)break;Math.abs(i.chroma-r)N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.secondaryContainer,N.secondary,15,"nearer",!1)}),N.onSecondaryContainer=_.fromPalette({name:"on_secondary_container",palette:t=>t.secondaryPalette,tone:t=>F(t)?_.foregroundTone(N.secondaryContainer.tone(t),4.5):t.isDark?90:10,background:t=>N.secondaryContainer,contrastCurve:new O(4.5,7,11,21)}),N.tertiary=_.fromPalette({name:"tertiary",palette:t=>t.tertiaryPalette,tone:t=>A(t)?t.isDark?90:25:t.isDark?80:40,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(3,4.5,7,11),toneDeltaPair:t=>new I(N.tertiaryContainer,N.tertiary,15,"nearer",!1)}),N.onTertiary=_.fromPalette({name:"on_tertiary",palette:t=>t.tertiaryPalette,tone:t=>A(t)?t.isDark?10:90:t.isDark?20:100,background:t=>N.tertiary,contrastCurve:new O(4.5,7,11,21)}),N.tertiaryContainer=_.fromPalette({name:"tertiary_container",palette:t=>t.tertiaryPalette,tone:t=>{if(A(t))return t.isDark?60:49;if(!F(t))return t.isDark?30:90;const r=S(t.tertiaryPalette.getHct(t.sourceColorHct.tone),t),e=t.tertiaryPalette.getHct(r);return x.fixIfDisliked(e).tone},isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.tertiaryContainer,N.tertiary,15,"nearer",!1)}),N.onTertiaryContainer=_.fromPalette({name:"on_tertiary_container",palette:t=>t.tertiaryPalette,tone:t=>A(t)?t.isDark?0:100:F(t)?_.foregroundTone(N.tertiaryContainer.tone(t),4.5):t.isDark?90:10,background:t=>N.tertiaryContainer,contrastCurve:new O(4.5,7,11,21)}),N.error=_.fromPalette({name:"error",palette:t=>t.errorPalette,tone:t=>t.isDark?80:40,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(3,4.5,7,11),toneDeltaPair:t=>new I(N.errorContainer,N.error,15,"nearer",!1)}),N.onError=_.fromPalette({name:"on_error",palette:t=>t.errorPalette,tone:t=>t.isDark?20:100,background:t=>N.error,contrastCurve:new O(4.5,7,11,21)}),N.errorContainer=_.fromPalette({name:"error_container",palette:t=>t.errorPalette,tone:t=>t.isDark?30:90,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.errorContainer,N.error,15,"nearer",!1)}),N.onErrorContainer=_.fromPalette({name:"on_error_container",palette:t=>t.errorPalette,tone:t=>t.isDark?90:10,background:t=>N.errorContainer,contrastCurve:new O(4.5,7,11,21)}),N.primaryFixed=_.fromPalette({name:"primary_fixed",palette:t=>t.primaryPalette,tone:t=>A(t)?40:90,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.primaryFixed,N.primaryFixedDim,10,"lighter",!0)}),N.primaryFixedDim=_.fromPalette({name:"primary_fixed_dim",palette:t=>t.primaryPalette,tone:t=>A(t)?30:80,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.primaryFixed,N.primaryFixedDim,10,"lighter",!0)}),N.onPrimaryFixed=_.fromPalette({name:"on_primary_fixed",palette:t=>t.primaryPalette,tone:t=>A(t)?100:10,background:t=>N.primaryFixedDim,secondBackground:t=>N.primaryFixed,contrastCurve:new O(4.5,7,11,21)}),N.onPrimaryFixedVariant=_.fromPalette({name:"on_primary_fixed_variant",palette:t=>t.primaryPalette,tone:t=>A(t)?90:30,background:t=>N.primaryFixedDim,secondBackground:t=>N.primaryFixed,contrastCurve:new O(3,4.5,7,11)}),N.secondaryFixed=_.fromPalette({name:"secondary_fixed",palette:t=>t.secondaryPalette,tone:t=>A(t)?80:90,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.secondaryFixed,N.secondaryFixedDim,10,"lighter",!0)}),N.secondaryFixedDim=_.fromPalette({name:"secondary_fixed_dim",palette:t=>t.secondaryPalette,tone:t=>A(t)?70:80,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.secondaryFixed,N.secondaryFixedDim,10,"lighter",!0)}),N.onSecondaryFixed=_.fromPalette({name:"on_secondary_fixed",palette:t=>t.secondaryPalette,tone:t=>10,background:t=>N.secondaryFixedDim,secondBackground:t=>N.secondaryFixed,contrastCurve:new O(4.5,7,11,21)}),N.onSecondaryFixedVariant=_.fromPalette({name:"on_secondary_fixed_variant",palette:t=>t.secondaryPalette,tone:t=>A(t)?25:30,background:t=>N.secondaryFixedDim,secondBackground:t=>N.secondaryFixed,contrastCurve:new O(3,4.5,7,11)}),N.tertiaryFixed=_.fromPalette({name:"tertiary_fixed",palette:t=>t.tertiaryPalette,tone:t=>A(t)?40:90,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.tertiaryFixed,N.tertiaryFixedDim,10,"lighter",!0)}),N.tertiaryFixedDim=_.fromPalette({name:"tertiary_fixed_dim",palette:t=>t.tertiaryPalette,tone:t=>A(t)?30:80,isBackground:!0,background:t=>N.highestSurface(t),contrastCurve:new O(1,1,3,7),toneDeltaPair:t=>new I(N.tertiaryFixed,N.tertiaryFixedDim,10,"lighter",!0)}),N.onTertiaryFixed=_.fromPalette({name:"on_tertiary_fixed",palette:t=>t.tertiaryPalette,tone:t=>A(t)?100:10,background:t=>N.tertiaryFixedDim,secondBackground:t=>N.tertiaryFixed,contrastCurve:new O(4.5,7,11,21)}),N.onTertiaryFixedVariant=_.fromPalette({name:"on_tertiary_fixed_variant",palette:t=>t.tertiaryPalette,tone:t=>A(t)?90:30,background:t=>N.tertiaryFixedDim,secondBackground:t=>N.tertiaryFixed,contrastCurve:new O(3,4.5,7,11)}); -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -class T{static fromInt(t){const r=M.fromInt(t);return T.fromHct(r)}static fromHct(t){return new T(t.hue,t.chroma,t)}static fromHueAndChroma(t,r){return new T(t,r,T.createKeyColor(t,r))}constructor(t,r,e){this.hue=t,this.chroma=r,this.keyColor=e,this.cache=new Map}static createKeyColor(t,r){let e=M.from(t,r,50),n=Math.abs(e.chroma-r);for(let a=1;a<50;a+=1){if(Math.round(r)===Math.round(e.chroma))return e;const o=M.from(t,r,50+a),i=Math.abs(o.chroma-r);i>>0}function R(t){return parseInt(t,16)} -/** - * @license - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */const $=t=>t.split("").map(((t,r)=>t.toUpperCase()===t?`${0!==r?"-":""}${t.toLowerCase()}`:t)).join(""),V=t=>{const{primary:r,...e}=t,n=j(r),a=B.light(n),o=B.dark(n);a.props.onInverseSurface=a.props.inverseOnSurface,delete a.props.inverseOnSurface,o.onInverseSurface=o.props.inverseOnSurface,delete o.props.inverseOnSurface;const i={transparent:"transparent",current:"currentColor",black:"#000000",white:"#ffffff"};return Object.keys(a.props).forEach((t=>{if(!["shadow","scrim"].includes(t)){const r=$(t);i[`${r}-light`]=L(a.props[t]),i[`${r}-dark`]=L(o.props[t])}})),Object.keys(e).forEach((t=>{const r=e[t],a="string"==typeof r?r:r.hex,o=r===a||r.harmonize,{light:s,dark:c}=function(t,r){let e=r.value;const n=e,a=t;r.blend&&(e=C.harmonize(n,a));const o=E.of(e).a1;return{color:r,value:e,light:{color:o.tone(40),onColor:o.tone(100),colorContainer:o.tone(90),onColorContainer:o.tone(10)},dark:{color:o.tone(80),onColor:o.tone(20),colorContainer:o.tone(30),onColorContainer:o.tone(90)}}}(n,{value:j(a),blend:o}),l=$(t);i[`${l}-light`]=L(s.color),i[`on-${l}-light`]=L(s.onColor),i[`${l}-container-light`]=L(s.colorContainer),i[`on-${l}-container-light`]=L(s.onColorContainer),i[`${l}-dark`]=L(c.color),i[`on-${l}-dark`]=L(c.onColor),i[`${l}-container-dark`]=L(c.colorContainer),i[`on-${l}-container-dark`]=L(c.onColorContainer)})),i};"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var q={},z={};!function(t){function r(t,r){return{handler:t,config:r}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:()=>e}),r.withOptions=function(t,r=(()=>({}))){const e=function(e){return{__options:e,handler:t(e),config:r(e)}};return e.__isOptionsFunction=!0,e.__pluginFunction=t,e.__configFunction=r,e};const e=r}(z),function(t){Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:()=>e});function r(t){return t&&t.__esModule?t:{default:t}}const e=r(z).default}(q);var U=(q.__esModule?q:{default:q}).default,H={exports:{}};H.exports=function(){for(var t=function(t,r,e){return void 0===r&&(r=0),void 0===e&&(e=1),te?e:t},r=t,e=function(t){t._clipped=!1,t._unclipped=t.slice(0);for(var e=0;e<=3;e++)e<3?((t[e]<0||t[e]>255)&&(t._clipped=!0),t[e]=r(t[e],0,255)):3===e&&(t[e]=r(t[e],0,1));return t},n={},a=0,o=["Boolean","Number","String","Function","Array","Date","RegExp","Undefined","Null"];a=3?Array.prototype.slice.call(t):"object"==c(t[0])&&r?r.split("").filter((function(r){return void 0!==t[0][r]})).map((function(r){return t[0][r]})):t[0]},u=s,f=function(t){if(t.length<2)return null;var r=t.length-1;return"string"==u(t[r])?t[r].toLowerCase():null},h=Math.PI,d={clip_rgb:e,limit:t,type:s,unpack:l,last:f,PI:h,TWOPI:2*h,PITHIRD:h/3,DEG2RAD:h/180,RAD2DEG:180/h},p={format:{},autodetect:[]},g=d.last,b=d.clip_rgb,m=d.type,v=p,y=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=this;if("object"===m(t[0])&&t[0].constructor&&t[0].constructor===this.constructor)return t[0];var n=g(t),a=!1;if(!n){a=!0,v.sorted||(v.autodetect=v.autodetect.sort((function(t,r){return r.p-t.p})),v.sorted=!0);for(var o=0,i=v.autodetect;o4?t[4]:1;return 1===o?[0,0,0,i]:[e>=1?0:255*(1-e)*(1-o),n>=1?0:255*(1-n)*(1-o),a>=1?0:255*(1-a)*(1-o),i]},I=O,F=M,A=k,S=p,N=d.unpack,T=d.type,E=_;A.prototype.cmyk=function(){return E(this._rgb)},F.cmyk=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(A,[null].concat(t,["cmyk"])))},S.format.cmyk=I,S.autodetect.push({p:2,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=N(t,"cmyk"),"array"===T(t)&&4===t.length)return"cmyk"}});var B=d.unpack,L=d.last,j=function(t){return Math.round(100*t)/100},R=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=B(t,"hsla"),n=L(t)||"lsa";return e[0]=j(e[0]||0),e[1]=j(100*e[1])+"%",e[2]=j(100*e[2])+"%","hsla"===n||e.length>3&&e[3]<1?(e[3]=e.length>3?e[3]:1,n="hsla"):e.length=3,n+"("+e.join(",")+")"},$=R,V=d.unpack,q=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=(t=V(t,"rgba"))[0],n=t[1],a=t[2];e/=255,n/=255,a/=255;var o,i,s=Math.min(e,n,a),c=Math.max(e,n,a),l=(c+s)/2;return c===s?(o=0,i=Number.NaN):o=l<.5?(c-s)/(c+s):(c-s)/(2-c-s),e==c?i=(n-a)/(c-s):n==c?i=2+(a-e)/(c-s):a==c&&(i=4+(e-n)/(c-s)),(i*=60)<0&&(i+=360),t.length>3&&void 0!==t[3]?[i,o,l,t[3]]:[i,o,l]},z=q,U=d.unpack,H=d.last,G=$,Y=z,K=Math.round,X=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=U(t,"rgba"),n=H(t)||"rgb";return"hsl"==n.substr(0,3)?G(Y(e),n):(e[0]=K(e[0]),e[1]=K(e[1]),e[2]=K(e[2]),("rgba"===n||e.length>3&&e[3]<1)&&(e[3]=e.length>3?e[3]:1,n="rgba"),n+"("+e.slice(0,"rgb"===n?3:4).join(",")+")")},J=X,W=d.unpack,Z=Math.round,Q=function(){for(var t,r=[],e=arguments.length;e--;)r[e]=arguments[e];var n,a,o,i=(r=W(r,"hsl"))[0],s=r[1],c=r[2];if(0===s)n=a=o=255*c;else{var l=[0,0,0],u=[0,0,0],f=c<.5?c*(1+s):c+s-c*s,h=2*c-f,d=i/360;l[0]=d+1/3,l[1]=d,l[2]=d-1/3;for(var p=0;p<3;p++)l[p]<0&&(l[p]+=1),l[p]>1&&(l[p]-=1),6*l[p]<1?u[p]=h+6*(f-h)*l[p]:2*l[p]<1?u[p]=f:3*l[p]<2?u[p]=h+(f-h)*(2/3-l[p])*6:u[p]=h;n=(t=[Z(255*u[0]),Z(255*u[1]),Z(255*u[2])])[0],a=t[1],o=t[2]}return r.length>3?[n,a,o,r[3]]:[n,a,o,1]},tt=Q,rt=tt,et=p,nt=/^rgb\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*\)$/,at=/^rgba\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*([01]|[01]?\.\d+)\)$/,ot=/^rgb\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/,it=/^rgba\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/,st=/^hsl\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/,ct=/^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/,lt=Math.round,ut=function(t){var r;if(t=t.toLowerCase().trim(),et.format.named)try{return et.format.named(t)}catch(t){}if(r=t.match(nt)){for(var e=r.slice(1,4),n=0;n<3;n++)e[n]=+e[n];return e[3]=1,e}if(r=t.match(at)){for(var a=r.slice(1,5),o=0;o<4;o++)a[o]=+a[o];return a}if(r=t.match(ot)){for(var i=r.slice(1,4),s=0;s<3;s++)i[s]=lt(2.55*i[s]);return i[3]=1,i}if(r=t.match(it)){for(var c=r.slice(1,5),l=0;l<3;l++)c[l]=lt(2.55*c[l]);return c[3]=+c[3],c}if(r=t.match(st)){var u=r.slice(1,4);u[1]*=.01,u[2]*=.01;var f=rt(u);return f[3]=1,f}if(r=t.match(ct)){var h=r.slice(1,4);h[1]*=.01,h[2]*=.01;var d=rt(h);return d[3]=+r[4],d}};ut.test=function(t){return nt.test(t)||at.test(t)||ot.test(t)||it.test(t)||st.test(t)||ct.test(t)};var ft=ut,ht=M,dt=k,pt=p,gt=d.type,bt=J,mt=ft;dt.prototype.css=function(t){return bt(this._rgb,t)},ht.css=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(dt,[null].concat(t,["css"])))},pt.format.css=mt,pt.autodetect.push({p:5,test:function(t){for(var r=[],e=arguments.length-1;e-- >0;)r[e]=arguments[e+1];if(!r.length&&"string"===gt(t)&&mt.test(t))return"css"}});var vt=k,yt=M,kt=p,wt=d.unpack;kt.format.gl=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=wt(t,"rgba");return e[0]*=255,e[1]*=255,e[2]*=255,e},yt.gl=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(vt,[null].concat(t,["gl"])))},vt.prototype.gl=function(){var t=this._rgb;return[t[0]/255,t[1]/255,t[2]/255,t[3]]};var Mt=d.unpack,Ct=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e,n=Mt(t,"rgb"),a=n[0],o=n[1],i=n[2],s=Math.min(a,o,i),c=Math.max(a,o,i),l=c-s,u=100*l/255,f=s/(255-l)*100;return 0===l?e=Number.NaN:(a===c&&(e=(o-i)/l),o===c&&(e=2+(i-a)/l),i===c&&(e=4+(a-o)/l),(e*=60)<0&&(e+=360)),[e,u,f]},Pt=Ct,xt=d.unpack,_t=Math.floor,Dt=function(){for(var t,r,e,n,a,o,i=[],s=arguments.length;s--;)i[s]=arguments[s];var c,l,u,f=(i=xt(i,"hcg"))[0],h=i[1],d=i[2];d*=255;var p=255*h;if(0===h)c=l=u=d;else{360===f&&(f=0),f>360&&(f-=360),f<0&&(f+=360);var g=_t(f/=60),b=f-g,m=d*(1-h),v=m+p*(1-b),y=m+p*b,k=m+p;switch(g){case 0:c=(t=[k,y,m])[0],l=t[1],u=t[2];break;case 1:c=(r=[v,k,m])[0],l=r[1],u=r[2];break;case 2:c=(e=[m,k,y])[0],l=e[1],u=e[2];break;case 3:c=(n=[m,v,k])[0],l=n[1],u=n[2];break;case 4:c=(a=[y,m,k])[0],l=a[1],u=a[2];break;case 5:c=(o=[k,m,v])[0],l=o[1],u=o[2]}}return[c,l,u,i.length>3?i[3]:1]},Ot=Dt,It=d.unpack,Ft=d.type,At=M,St=k,Nt=p,Tt=Pt;St.prototype.hcg=function(){return Tt(this._rgb)},At.hcg=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(St,[null].concat(t,["hcg"])))},Nt.format.hcg=Ot,Nt.autodetect.push({p:1,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=It(t,"hcg"),"array"===Ft(t)&&3===t.length)return"hcg"}});var Et=d.unpack,Bt=d.last,Lt=Math.round,jt=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=Et(t,"rgba"),n=e[0],a=e[1],o=e[2],i=e[3],s=Bt(t)||"auto";void 0===i&&(i=1),"auto"===s&&(s=i<1?"rgba":"rgb");var c="000000"+((n=Lt(n))<<16|(a=Lt(a))<<8|(o=Lt(o))).toString(16);c=c.substr(c.length-6);var l="0"+Lt(255*i).toString(16);switch(l=l.substr(l.length-2),s.toLowerCase()){case"rgba":return"#"+c+l;case"argb":return"#"+l+c;default:return"#"+c}},Rt=jt,$t=/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,Vt=/^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/,qt=function(t){if(t.match($t)){4!==t.length&&7!==t.length||(t=t.substr(1)),3===t.length&&(t=(t=t.split(""))[0]+t[0]+t[1]+t[1]+t[2]+t[2]);var r=parseInt(t,16);return[r>>16,r>>8&255,255&r,1]}if(t.match(Vt)){5!==t.length&&9!==t.length||(t=t.substr(1)),4===t.length&&(t=(t=t.split(""))[0]+t[0]+t[1]+t[1]+t[2]+t[2]+t[3]+t[3]);var e=parseInt(t,16);return[e>>24&255,e>>16&255,e>>8&255,Math.round((255&e)/255*100)/100]}throw new Error("unknown hex color: "+t)},zt=M,Ut=k,Ht=d.type,Gt=p,Yt=Rt;Ut.prototype.hex=function(t){return Yt(this._rgb,t)},zt.hex=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(Ut,[null].concat(t,["hex"])))},Gt.format.hex=qt,Gt.autodetect.push({p:4,test:function(t){for(var r=[],e=arguments.length-1;e-- >0;)r[e]=arguments[e+1];if(!r.length&&"string"===Ht(t)&&[3,4,5,6,7,8,9].indexOf(t.length)>=0)return"hex"}});var Kt=d.unpack,Xt=d.TWOPI,Jt=Math.min,Wt=Math.sqrt,Zt=Math.acos,Qt=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e,n=Kt(t,"rgb"),a=n[0],o=n[1],i=n[2],s=Jt(a/=255,o/=255,i/=255),c=(a+o+i)/3,l=c>0?1-s/c:0;return 0===l?e=NaN:(e=(a-o+(a-i))/2,e/=Wt((a-o)*(a-o)+(a-i)*(o-i)),e=Zt(e),i>o&&(e=Xt-e),e/=Xt),[360*e,l,c]},tr=Qt,rr=d.unpack,er=d.limit,nr=d.TWOPI,ar=d.PITHIRD,or=Math.cos,ir=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e,n,a,o=(t=rr(t,"hsi"))[0],i=t[1],s=t[2];return isNaN(o)&&(o=0),isNaN(i)&&(i=0),o>360&&(o-=360),o<0&&(o+=360),(o/=360)<1/3?n=1-((a=(1-i)/3)+(e=(1+i*or(nr*o)/or(ar-nr*o))/3)):o<2/3?a=1-((e=(1-i)/3)+(n=(1+i*or(nr*(o-=1/3))/or(ar-nr*o))/3)):e=1-((n=(1-i)/3)+(a=(1+i*or(nr*(o-=2/3))/or(ar-nr*o))/3)),[255*(e=er(s*e*3)),255*(n=er(s*n*3)),255*(a=er(s*a*3)),t.length>3?t[3]:1]},sr=ir,cr=d.unpack,lr=d.type,ur=M,fr=k,hr=p,dr=tr;fr.prototype.hsi=function(){return dr(this._rgb)},ur.hsi=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(fr,[null].concat(t,["hsi"])))},hr.format.hsi=sr,hr.autodetect.push({p:2,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=cr(t,"hsi"),"array"===lr(t)&&3===t.length)return"hsi"}});var pr=d.unpack,gr=d.type,br=M,mr=k,vr=p,yr=z;mr.prototype.hsl=function(){return yr(this._rgb)},br.hsl=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(mr,[null].concat(t,["hsl"])))},vr.format.hsl=tt,vr.autodetect.push({p:2,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=pr(t,"hsl"),"array"===gr(t)&&3===t.length)return"hsl"}});var kr=d.unpack,wr=Math.min,Mr=Math.max,Cr=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e,n,a,o=(t=kr(t,"rgb"))[0],i=t[1],s=t[2],c=wr(o,i,s),l=Mr(o,i,s),u=l-c;return a=l/255,0===l?(e=Number.NaN,n=0):(n=u/l,o===l&&(e=(i-s)/u),i===l&&(e=2+(s-o)/u),s===l&&(e=4+(o-i)/u),(e*=60)<0&&(e+=360)),[e,n,a]},Pr=Cr,xr=d.unpack,_r=Math.floor,Dr=function(){for(var t,r,e,n,a,o,i=[],s=arguments.length;s--;)i[s]=arguments[s];var c,l,u,f=(i=xr(i,"hsv"))[0],h=i[1],d=i[2];if(d*=255,0===h)c=l=u=d;else{360===f&&(f=0),f>360&&(f-=360),f<0&&(f+=360);var p=_r(f/=60),g=f-p,b=d*(1-h),m=d*(1-h*g),v=d*(1-h*(1-g));switch(p){case 0:c=(t=[d,v,b])[0],l=t[1],u=t[2];break;case 1:c=(r=[m,d,b])[0],l=r[1],u=r[2];break;case 2:c=(e=[b,d,v])[0],l=e[1],u=e[2];break;case 3:c=(n=[b,m,d])[0],l=n[1],u=n[2];break;case 4:c=(a=[v,b,d])[0],l=a[1],u=a[2];break;case 5:c=(o=[d,b,m])[0],l=o[1],u=o[2]}}return[c,l,u,i.length>3?i[3]:1]},Or=Dr,Ir=d.unpack,Fr=d.type,Ar=M,Sr=k,Nr=p,Tr=Pr;Sr.prototype.hsv=function(){return Tr(this._rgb)},Ar.hsv=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(Sr,[null].concat(t,["hsv"])))},Nr.format.hsv=Or,Nr.autodetect.push({p:2,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=Ir(t,"hsv"),"array"===Fr(t)&&3===t.length)return"hsv"}});var Er={Kn:18,Xn:.95047,Yn:1,Zn:1.08883,t0:.137931034,t1:.206896552,t2:.12841855,t3:.008856452},Br=Er,Lr=d.unpack,jr=Math.pow,Rr=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=Lr(t,"rgb"),n=e[0],a=e[1],o=e[2],i=qr(n,a,o),s=i[0],c=i[1],l=116*c-16;return[l<0?0:l,500*(s-c),200*(c-i[2])]},$r=function(t){return(t/=255)<=.04045?t/12.92:jr((t+.055)/1.055,2.4)},Vr=function(t){return t>Br.t3?jr(t,1/3):t/Br.t2+Br.t0},qr=function(t,r,e){return t=$r(t),r=$r(r),e=$r(e),[Vr((.4124564*t+.3575761*r+.1804375*e)/Br.Xn),Vr((.2126729*t+.7151522*r+.072175*e)/Br.Yn),Vr((.0193339*t+.119192*r+.9503041*e)/Br.Zn)]},zr=Rr,Ur=Er,Hr=d.unpack,Gr=Math.pow,Yr=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e,n,a,o=(t=Hr(t,"lab"))[0],i=t[1],s=t[2];return n=(o+16)/116,e=isNaN(i)?n:n+i/500,a=isNaN(s)?n:n-s/200,n=Ur.Yn*Xr(n),e=Ur.Xn*Xr(e),a=Ur.Zn*Xr(a),[Kr(3.2404542*e-1.5371385*n-.4985314*a),Kr(-.969266*e+1.8760108*n+.041556*a),Kr(.0556434*e-.2040259*n+1.0572252*a),t.length>3?t[3]:1]},Kr=function(t){return 255*(t<=.00304?12.92*t:1.055*Gr(t,1/2.4)-.055)},Xr=function(t){return t>Ur.t1?t*t*t:Ur.t2*(t-Ur.t0)},Jr=Yr,Wr=d.unpack,Zr=d.type,Qr=M,te=k,re=p,ee=zr;te.prototype.lab=function(){return ee(this._rgb)},Qr.lab=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(te,[null].concat(t,["lab"])))},re.format.lab=Jr,re.autodetect.push({p:2,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=Wr(t,"lab"),"array"===Zr(t)&&3===t.length)return"lab"}});var ne=d.unpack,ae=d.RAD2DEG,oe=Math.sqrt,ie=Math.atan2,se=Math.round,ce=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=ne(t,"lab"),n=e[0],a=e[1],o=e[2],i=oe(a*a+o*o),s=(ie(o,a)*ae+360)%360;return 0===se(1e4*i)&&(s=Number.NaN),[n,i,s]},le=ce,ue=d.unpack,fe=zr,he=le,de=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=ue(t,"rgb"),n=e[0],a=e[1],o=e[2],i=fe(n,a,o),s=i[0],c=i[1],l=i[2];return he(s,c,l)},pe=de,ge=d.unpack,be=d.DEG2RAD,me=Math.sin,ve=Math.cos,ye=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=ge(t,"lch"),n=e[0],a=e[1],o=e[2];return isNaN(o)&&(o=0),[n,ve(o*=be)*a,me(o)*a]},ke=ye,we=d.unpack,Me=ke,Ce=Jr,Pe=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=(t=we(t,"lch"))[0],n=t[1],a=t[2],o=Me(e,n,a),i=o[0],s=o[1],c=o[2],l=Ce(i,s,c);return[l[0],l[1],l[2],t.length>3?t[3]:1]},xe=Pe,_e=d.unpack,De=xe,Oe=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=_e(t,"hcl").reverse();return De.apply(void 0,e)},Ie=Oe,Fe=d.unpack,Ae=d.type,Se=M,Ne=k,Te=p,Ee=pe;Ne.prototype.lch=function(){return Ee(this._rgb)},Ne.prototype.hcl=function(){return Ee(this._rgb).reverse()},Se.lch=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(Ne,[null].concat(t,["lch"])))},Se.hcl=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(Ne,[null].concat(t,["hcl"])))},Te.format.lch=xe,Te.format.hcl=Ie,["lch","hcl"].forEach((function(t){return Te.autodetect.push({p:2,test:function(){for(var r=[],e=arguments.length;e--;)r[e]=arguments[e];if(r=Fe(r,t),"array"===Ae(r)&&3===r.length)return t}})}));var Be={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflower:"#6495ed",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",laserlemon:"#ffff54",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrod:"#fafad2",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",maroon2:"#7f0000",maroon3:"#b03060",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",purple2:"#7f007f",purple3:"#a020f0",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},Le=k,je=p,Re=d.type,$e=Be,Ve=qt,qe=Rt;Le.prototype.name=function(){for(var t=qe(this._rgb,"rgb"),r=0,e=Object.keys($e);r0;)r[e]=arguments[e+1];if(!r.length&&"string"===Re(t)&&$e[t.toLowerCase()])return"named"}});var ze=d.unpack,Ue=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=ze(t,"rgb");return(e[0]<<16)+(e[1]<<8)+e[2]},He=Ue,Ge=d.type,Ye=function(t){if("number"==Ge(t)&&t>=0&&t<=16777215)return[t>>16,t>>8&255,255&t,1];throw new Error("unknown num color: "+t)},Ke=Ye,Xe=M,Je=k,We=p,Ze=d.type,Qe=He;Je.prototype.num=function(){return Qe(this._rgb)},Xe.num=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(Je,[null].concat(t,["num"])))},We.format.num=Ke,We.autodetect.push({p:5,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(1===t.length&&"number"===Ze(t[0])&&t[0]>=0&&t[0]<=16777215)return"num"}});var tn=M,rn=k,en=p,nn=d.unpack,an=d.type,on=Math.round;rn.prototype.rgb=function(t){return void 0===t&&(t=!0),!1===t?this._rgb.slice(0,3):this._rgb.slice(0,3).map(on)},rn.prototype.rgba=function(t){return void 0===t&&(t=!0),this._rgb.slice(0,4).map((function(r,e){return e<3?!1===t?r:on(r):r}))},tn.rgb=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(rn,[null].concat(t,["rgb"])))},en.format.rgb=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=nn(t,"rgba");return void 0===e[3]&&(e[3]=1),e},en.autodetect.push({p:3,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=nn(t,"rgba"),"array"===an(t)&&(3===t.length||4===t.length&&"number"==an(t[3])&&t[3]>=0&&t[3]<=1))return"rgb"}});var sn=Math.log,cn=function(t){var r,e,n,a=t/100;return a<66?(r=255,e=a<6?0:-155.25485562709179-.44596950469579133*(e=a-2)+104.49216199393888*sn(e),n=a<20?0:.8274096064007395*(n=a-10)-254.76935184120902+115.67994401066147*sn(n)):(r=351.97690566805693+.114206453784165*(r=a-55)-40.25366309332127*sn(r),e=325.4494125711974+.07943456536662342*(e=a-50)-28.0852963507957*sn(e),n=255),[r,e,n,1]},ln=cn,un=d.unpack,fn=Math.round,hn=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];for(var e,n=un(t,"rgb"),a=n[0],o=n[2],i=1e3,s=4e4,c=.4;s-i>c;){var l=ln(e=.5*(s+i));l[2]/l[0]>=o/a?s=e:i=e}return fn(e)},dn=M,pn=k,gn=p,bn=hn;pn.prototype.temp=pn.prototype.kelvin=pn.prototype.temperature=function(){return bn(this._rgb)},dn.temp=dn.kelvin=dn.temperature=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(pn,[null].concat(t,["temp"])))},gn.format.temp=gn.format.kelvin=gn.format.temperature=cn;var mn=d.unpack,vn=Math.cbrt,yn=Math.pow,kn=Math.sign,wn=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=mn(t,"rgb"),n=e[0],a=e[1],o=e[2],i=[Cn(n/255),Cn(a/255),Cn(o/255)],s=i[0],c=i[1],l=i[2],u=vn(.4122214708*s+.5363325363*c+.0514459929*l),f=vn(.2119034982*s+.6806995451*c+.1073969566*l),h=vn(.0883024619*s+.2817188376*c+.6299787005*l);return[.2104542553*u+.793617785*f-.0040720468*h,1.9779984951*u-2.428592205*f+.4505937099*h,.0259040371*u+.7827717662*f-.808675766*h]},Mn=wn;function Cn(t){var r=Math.abs(t);return r<.04045?t/12.92:(kn(t)||1)*yn((r+.055)/1.055,2.4)}var Pn=d.unpack,xn=Math.pow,_n=Math.sign,Dn=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=(t=Pn(t,"lab"))[0],n=t[1],a=t[2],o=xn(e+.3963377774*n+.2158037573*a,3),i=xn(e-.1055613458*n-.0638541728*a,3),s=xn(e-.0894841775*n-1.291485548*a,3);return[255*In(4.0767416621*o-3.3077115913*i+.2309699292*s),255*In(-1.2684380046*o+2.6097574011*i-.3413193965*s),255*In(-.0041960863*o-.7034186147*i+1.707614701*s),t.length>3?t[3]:1]},On=Dn;function In(t){var r=Math.abs(t);return r>.0031308?(_n(t)||1)*(1.055*xn(r,1/2.4)-.055):12.92*t}var Fn=d.unpack,An=d.type,Sn=M,Nn=k,Tn=p,En=Mn;Nn.prototype.oklab=function(){return En(this._rgb)},Sn.oklab=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(Nn,[null].concat(t,["oklab"])))},Tn.format.oklab=On,Tn.autodetect.push({p:3,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=Fn(t,"oklab"),"array"===An(t)&&3===t.length)return"oklab"}});var Bn=d.unpack,Ln=Mn,jn=le,Rn=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=Bn(t,"rgb"),n=e[0],a=e[1],o=e[2],i=Ln(n,a,o),s=i[0],c=i[1],l=i[2];return jn(s,c,l)},$n=Rn,Vn=d.unpack,qn=ke,zn=On,Un=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];var e=(t=Vn(t,"lch"))[0],n=t[1],a=t[2],o=qn(e,n,a),i=o[0],s=o[1],c=o[2],l=zn(i,s,c);return[l[0],l[1],l[2],t.length>3?t[3]:1]},Hn=Un,Gn=d.unpack,Yn=d.type,Kn=M,Xn=k,Jn=p,Wn=$n;Xn.prototype.oklch=function(){return Wn(this._rgb)},Kn.oklch=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return new(Function.prototype.bind.apply(Xn,[null].concat(t,["oklch"])))},Jn.format.oklch=Hn,Jn.autodetect.push({p:3,test:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];if(t=Gn(t,"oklch"),"array"===Yn(t)&&3===t.length)return"oklch"}});var Zn=k,Qn=d.type;Zn.prototype.alpha=function(t,r){return void 0===r&&(r=!1),void 0!==t&&"number"===Qn(t)?r?(this._rgb[3]=t,this):new Zn([this._rgb[0],this._rgb[1],this._rgb[2],t],"rgb"):this._rgb[3]},k.prototype.clipped=function(){return this._rgb._clipped||!1};var ta=k,ra=Er;ta.prototype.darken=function(t){void 0===t&&(t=1);var r=this,e=r.lab();return e[0]-=ra.Kn*t,new ta(e,"lab").alpha(r.alpha(),!0)},ta.prototype.brighten=function(t){return void 0===t&&(t=1),this.darken(-t)},ta.prototype.darker=ta.prototype.darken,ta.prototype.brighter=ta.prototype.brighten,k.prototype.get=function(t){var r=t.split("."),e=r[0],n=r[1],a=this[e]();if(n){var o=e.indexOf(n)-("ok"===e.substr(0,2)?2:0);if(o>-1)return a[o];throw new Error("unknown channel "+n+" in mode "+e)}return a};var ea=k,na=d.type,aa=Math.pow,oa=1e-7,ia=20;ea.prototype.luminance=function(t){if(void 0!==t&&"number"===na(t)){if(0===t)return new ea([0,0,0,this._rgb[3]],"rgb");if(1===t)return new ea([255,255,255,this._rgb[3]],"rgb");var r=this.luminance(),e="rgb",n=ia,a=function(r,o){var i=r.interpolate(o,.5,e),s=i.luminance();return Math.abs(t-s)t?a(r,i):a(i,o)},o=(r>t?a(new ea([0,0,0]),this):a(this,new ea([255,255,255]))).rgb();return new ea(o.concat([this._rgb[3]]))}return sa.apply(void 0,this._rgb.slice(0,3))};var sa=function(t,r,e){return.2126*(t=ca(t))+.7152*(r=ca(r))+.0722*(e=ca(e))},ca=function(t){return(t/=255)<=.03928?t/12.92:aa((t+.055)/1.055,2.4)},la={},ua=k,fa=d.type,ha=la,da=function(t,r,e){void 0===e&&(e=.5);for(var n=[],a=arguments.length-3;a-- >0;)n[a]=arguments[a+3];var o=n[0]||"lrgb";if(ha[o]||n.length||(o=Object.keys(ha)[0]),!ha[o])throw new Error("interpolation mode "+o+" is not defined");return"object"!==fa(t)&&(t=new ua(t)),"object"!==fa(r)&&(r=new ua(r)),ha[o](t,r,e).alpha(t.alpha()+e*(r.alpha()-t.alpha()))},pa=k,ga=da;pa.prototype.mix=pa.prototype.interpolate=function(t,r){void 0===r&&(r=.5);for(var e=[],n=arguments.length-2;n-- >0;)e[n]=arguments[n+2];return ga.apply(void 0,[this,t,r].concat(e))};var ba=k;ba.prototype.premultiply=function(t){void 0===t&&(t=!1);var r=this._rgb,e=r[3];return t?(this._rgb=[r[0]*e,r[1]*e,r[2]*e,e],this):new ba([r[0]*e,r[1]*e,r[2]*e,e],"rgb")};var ma=k,va=Er;ma.prototype.saturate=function(t){void 0===t&&(t=1);var r=this,e=r.lch();return e[1]+=va.Kn*t,e[1]<0&&(e[1]=0),new ma(e,"lch").alpha(r.alpha(),!0)},ma.prototype.desaturate=function(t){return void 0===t&&(t=1),this.saturate(-t)};var ya=k,ka=d.type;ya.prototype.set=function(t,r,e){void 0===e&&(e=!1);var n=t.split("."),a=n[0],o=n[1],i=this[a]();if(o){var s=a.indexOf(o)-("ok"===a.substr(0,2)?2:0);if(s>-1){if("string"==ka(r))switch(r.charAt(0)){case"+":case"-":i[s]+=+r;break;case"*":i[s]*=+r.substr(1);break;case"/":i[s]/=+r.substr(1);break;default:i[s]=+r}else{if("number"!==ka(r))throw new Error("unsupported value for Color.set");i[s]=r}var c=new ya(i,a);return e?(this._rgb=c._rgb,this):c}throw new Error("unknown channel "+o+" in mode "+a)}return i};var wa=k,Ma=function(t,r,e){var n=t._rgb,a=r._rgb;return new wa(n[0]+e*(a[0]-n[0]),n[1]+e*(a[1]-n[1]),n[2]+e*(a[2]-n[2]),"rgb")};la.rgb=Ma;var Ca=k,Pa=Math.sqrt,xa=Math.pow,_a=function(t,r,e){var n=t._rgb,a=n[0],o=n[1],i=n[2],s=r._rgb,c=s[0],l=s[1],u=s[2];return new Ca(Pa(xa(a,2)*(1-e)+xa(c,2)*e),Pa(xa(o,2)*(1-e)+xa(l,2)*e),Pa(xa(i,2)*(1-e)+xa(u,2)*e),"rgb")};la.lrgb=_a;var Da=k,Oa=function(t,r,e){var n=t.lab(),a=r.lab();return new Da(n[0]+e*(a[0]-n[0]),n[1]+e*(a[1]-n[1]),n[2]+e*(a[2]-n[2]),"lab")};la.lab=Oa;var Ia=k,Fa=function(t,r,e,n){var a,o,i,s,c,l,u,f,h,d,p,g,b;return"hsl"===n?(i=t.hsl(),s=r.hsl()):"hsv"===n?(i=t.hsv(),s=r.hsv()):"hcg"===n?(i=t.hcg(),s=r.hcg()):"hsi"===n?(i=t.hsi(),s=r.hsi()):"lch"===n||"hcl"===n?(n="hcl",i=t.hcl(),s=r.hcl()):"oklch"===n&&(i=t.oklch().reverse(),s=r.oklch().reverse()),"h"!==n.substr(0,1)&&"oklch"!==n||(c=(a=i)[0],u=a[1],h=a[2],l=(o=s)[0],f=o[1],d=o[2]),isNaN(c)||isNaN(l)?isNaN(c)?isNaN(l)?g=Number.NaN:(g=l,1!=h&&0!=h||"hsv"==n||(p=f)):(g=c,1!=d&&0!=d||"hsv"==n||(p=u)):g=c+e*(l>c&&l-c>180?l-(c+360):l180?l+360-c:l-c),void 0===p&&(p=u+e*(f-u)),b=h+e*(d-h),new Ia("oklch"===n?[b,p,g]:[g,p,b],n)},Aa=Fa,Sa=function(t,r,e){return Aa(t,r,e,"lch")};la.lch=Sa,la.hcl=Sa;var Na=k,Ta=function(t,r,e){var n=t.num(),a=r.num();return new Na(n+e*(a-n),"num")};la.num=Ta;var Ea=Fa,Ba=function(t,r,e){return Ea(t,r,e,"hcg")};la.hcg=Ba;var La=Fa,ja=function(t,r,e){return La(t,r,e,"hsi")};la.hsi=ja;var Ra=Fa,$a=function(t,r,e){return Ra(t,r,e,"hsl")};la.hsl=$a;var Va=Fa,qa=function(t,r,e){return Va(t,r,e,"hsv")};la.hsv=qa;var za=k,Ua=function(t,r,e){var n=t.oklab(),a=r.oklab();return new za(n[0]+e*(a[0]-n[0]),n[1]+e*(a[1]-n[1]),n[2]+e*(a[2]-n[2]),"oklab")};la.oklab=Ua;var Ha=Fa,Ga=function(t,r,e){return Ha(t,r,e,"oklch")};la.oklch=Ga;var Ya=k,Ka=d.clip_rgb,Xa=Math.pow,Ja=Math.sqrt,Wa=Math.PI,Za=Math.cos,Qa=Math.sin,to=Math.atan2,ro=function(t,r,e){void 0===r&&(r="lrgb"),void 0===e&&(e=null);var n=t.length;e||(e=Array.from(new Array(n)).map((function(){return 1})));var a=n/e.reduce((function(t,r){return t+r}));if(e.forEach((function(t,r){e[r]*=a})),t=t.map((function(t){return new Ya(t)})),"lrgb"===r)return eo(t,e);for(var o=t.shift(),i=o.get(r),s=[],c=0,l=0,u=0;u=360;)p-=360;i[d]=p}else i[d]=i[d]/s[d];return h/=n,new Ya(i,r).alpha(h>.99999?1:h,!0)},eo=function(t,r){for(var e=t.length,n=[0,0,0,0],a=0;a.9999999&&(n[3]=1),new Ya(Ka(n))},no=M,ao=d.type,oo=Math.pow,io=function(t){var r="rgb",e=no("#ccc"),n=0,a=[0,1],o=[],i=[0,0],s=!1,c=[],l=!1,u=0,f=1,h=!1,d={},p=!0,g=1,b=function(t){if((t=t||["#fff","#000"])&&"string"===ao(t)&&no.brewer&&no.brewer[t.toLowerCase()]&&(t=no.brewer[t.toLowerCase()]),"array"===ao(t)){1===t.length&&(t=[t[0],t[0]]),t=t.slice(0);for(var r=0;r=s[e];)e++;return e-1}return 0},v=function(t){return t},y=function(t){return t},k=function(t,n){var a,l;if(null==n&&(n=!1),isNaN(t)||null===t)return e;l=n?t:s&&s.length>2?m(t)/(s.length-2):f!==u?(t-u)/(f-u):1,l=y(l),n||(l=v(l)),1!==g&&(l=oo(l,g)),l=i[0]+l*(1-i[0]-i[1]),l=Math.min(1,Math.max(0,l));var h=Math.floor(1e4*l);if(p&&d[h])a=d[h];else{if("array"===ao(c))for(var b=0;b=k&&b===o.length-1){a=c[b];break}if(l>k&&l2){var l=t.map((function(r,e){return e/(t.length-1)})),h=t.map((function(t){return(t-u)/(f-u)}));h.every((function(t,r){return l[r]===t}))||(y=function(t){if(t<=0||t>=1)return t;for(var r=0;t>=h[r+1];)r++;var e=(t-h[r])/(h[r+1]-h[r]);return l[r]+e*(l[r+1]-l[r])})}}return a=[u,f],M},M.mode=function(t){return arguments.length?(r=t,w(),M):r},M.range=function(t,r){return b(t),M},M.out=function(t){return l=t,M},M.spread=function(t){return arguments.length?(n=t,M):n},M.correctLightness=function(t){return null==t&&(t=!0),h=t,w(),v=h?function(t){for(var r=k(0,!0).lab()[0],e=k(1,!0).lab()[0],n=r>e,a=k(t,!0).lab()[0],o=r+(e-r)*t,i=a-o,s=0,c=1,l=20;Math.abs(i)>.01&&l-- >0;)n&&(i*=-1),i<0?(s=t,t+=.5*(c-t)):(c=t,t+=.5*(s-t)),a=k(t,!0).lab()[0],i=a-o;return t}:function(t){return t},M},M.padding=function(t){return null!=t?("number"===ao(t)&&(t=[t,t]),i=t,M):i},M.colors=function(r,e){arguments.length<2&&(e="hex");var n=[];if(0===arguments.length)n=c.slice(0);else if(1===r)n=[M(.5)];else if(r>1){var o=a[0],i=a[1]-o;n=so(0,r,!1).map((function(t){return M(o+t/(r-1)*i)}))}else{t=[];var l=[];if(s&&s.length>2)for(var u=1,f=s.length,h=1<=f;h?uf;h?u++:u--)l.push(.5*(s[u-1]+s[u]));else l=a;n=l.map((function(t){return M(t)}))}return no[e]&&(n=n.map((function(t){return t[e]()}))),n},M.cache=function(t){return null!=t?(p=t,M):p},M.gamma=function(t){return null!=t?(g=t,M):g},M.nodata=function(t){return null!=t?(e=no(t),M):e},M};function so(t,r,e){for(var n=[],a=to;a?i++:i--)n.push(i);return n}var co=k,lo=io,uo=function(t){for(var r=[1,1],e=1;e=5))throw new RangeError("No point in running bezier with only one color.");var l,u,f;l=t.map((function(t){return t.lab()})),f=t.length-1,u=uo(f),a=function(t){var r=1-t,e=[0,1,2].map((function(e){return l.reduce((function(n,a,o){return n+u[o]*Math.pow(r,f-o)*Math.pow(t,o)*a[e]}),0)}));return new co(e,"lab")}}return a},ho=function(t){var r=fo(t);return r.scale=function(){return lo(r)},r},po=M,go=function(t,r,e){if(!go[e])throw new Error("unknown blend mode "+e);return go[e](t,r)},bo=function(t){return function(r,e){var n=po(e).rgb(),a=po(r).rgb();return po.rgb(t(n,a))}},mo=function(t){return function(r,e){var n=[];return n[0]=t(r[0],e[0]),n[1]=t(r[1],e[1]),n[2]=t(r[2],e[2]),n}},vo=function(t){return t},yo=function(t,r){return t*r/255},ko=function(t,r){return t>r?r:t},wo=function(t,r){return t>r?t:r},Mo=function(t,r){return 255*(1-(1-t/255)*(1-r/255))},Co=function(t,r){return r<128?2*t*r/255:255*(1-2*(1-t/255)*(1-r/255))},Po=function(t,r){return 255*(1-(1-r/255)/(t/255))},xo=function(t,r){return 255===t||(t=r/255*255/(1-t/255))>255?255:t};go.normal=bo(mo(vo)),go.multiply=bo(mo(yo)),go.screen=bo(mo(Mo)),go.overlay=bo(mo(Co)),go.darken=bo(mo(ko)),go.lighten=bo(mo(wo)),go.dodge=bo(mo(xo)),go.burn=bo(mo(Po));for(var _o=go,Do=d.type,Oo=d.clip_rgb,Io=d.TWOPI,Fo=Math.pow,Ao=Math.sin,So=Math.cos,No=M,To=function(t,r,e,n,a){void 0===t&&(t=300),void 0===r&&(r=-1.5),void 0===e&&(e=1),void 0===n&&(n=1),void 0===a&&(a=[0,1]);var o,i=0;"array"===Do(a)?o=a[1]-a[0]:(o=0,a=[a,a]);var s=function(s){var c=Io*((t+120)/360+r*s),l=Fo(a[0]+o*s,n),u=(0!==i?e[0]+s*i:e)*l*(1-l)/2,f=So(c),h=Ao(c);return No(Oo([255*(l+u*(-.14861*f+1.78277*h)),255*(l+u*(-.29227*f-.90649*h)),255*(l+u*(1.97294*f)),1]))};return s.start=function(r){return null==r?t:(t=r,s)},s.rotations=function(t){return null==t?r:(r=t,s)},s.gamma=function(t){return null==t?n:(n=t,s)},s.hue=function(t){return null==t?e:("array"===Do(e=t)?0==(i=e[1]-e[0])&&(e=e[1]):i=0,s)},s.lightness=function(t){return null==t?a:("array"===Do(t)?(a=t,o=t[1]-t[0]):(a=[t,t],o=0),s)},s.scale=function(){return No.scale(s)},s.hue(e),s},Eo=k,Bo="0123456789abcdef",Lo=Math.floor,jo=Math.random,Ro=function(){for(var t="#",r=0;r<6;r++)t+=Bo.charAt(Lo(16*jo()));return new Eo(t,"hex")},$o=s,Vo=Math.log,qo=Math.pow,zo=Math.floor,Uo=Math.abs,Ho=function(t,r){void 0===r&&(r=null);var e={min:Number.MAX_VALUE,max:-1*Number.MAX_VALUE,sum:0,values:[],count:0};return"object"===$o(t)&&(t=Object.values(t)),t.forEach((function(t){r&&"object"===$o(t)&&(t=t[r]),null==t||isNaN(t)||(e.values.push(t),e.sum+=t,te.max&&(e.max=t),e.count+=1)})),e.domain=[e.min,e.max],e.limits=function(t,r){return Go(e,t,r)},e},Go=function(t,r,e){void 0===r&&(r="equal"),void 0===e&&(e=7),"array"==$o(t)&&(t=Ho(t));var n=t.min,a=t.max,o=t.values.sort((function(t,r){return t-r}));if(1===e)return[n,a];var i=[];if("c"===r.substr(0,1)&&(i.push(n),i.push(a)),"e"===r.substr(0,1)){i.push(n);for(var s=1;s 0");var c=Math.LOG10E*Vo(n),l=Math.LOG10E*Vo(a);i.push(n);for(var u=1;u200&&(y=!1)}for(var E={},B=0;Bn?(e+.05)/(n+.05):(n+.05)/(e+.05)},Jo=k,Wo=Math.sqrt,Zo=Math.pow,Qo=Math.min,ti=Math.max,ri=Math.atan2,ei=Math.abs,ni=Math.cos,ai=Math.sin,oi=Math.exp,ii=Math.PI,si=function(t,r,e,n,a){void 0===e&&(e=1),void 0===n&&(n=1),void 0===a&&(a=1);var o=function(t){return 360*t/(2*ii)},i=function(t){return 2*ii*t/360};t=new Jo(t),r=new Jo(r);var s=Array.from(t.lab()),c=s[0],l=s[1],u=s[2],f=Array.from(r.lab()),h=f[0],d=f[1],p=f[2],g=(c+h)/2,b=(Wo(Zo(l,2)+Zo(u,2))+Wo(Zo(d,2)+Zo(p,2)))/2,m=.5*(1-Wo(Zo(b,7)/(Zo(b,7)+Zo(25,7)))),v=l*(1+m),y=d*(1+m),k=Wo(Zo(v,2)+Zo(u,2)),w=Wo(Zo(y,2)+Zo(p,2)),M=(k+w)/2,C=o(ri(u,v)),P=o(ri(p,y)),x=C>=0?C:C+360,_=P>=0?P:P+360,D=ei(x-_)>180?(x+_+360)/2:(x+_)/2,O=1-.17*ni(i(D-30))+.24*ni(i(2*D))+.32*ni(i(3*D+6))-.2*ni(i(4*D-63)),I=_-x;I=ei(I)<=180?I:_<=x?I+360:I-360,I=2*Wo(k*w)*ai(i(I)/2);var F=h-c,A=w-k,S=1+.015*Zo(g-50,2)/Wo(20+Zo(g-50,2)),N=1+.045*M,T=1+.015*M*O,E=30*oi(-Zo((D-275)/25,2)),B=-2*Wo(Zo(M,7)/(Zo(M,7)+Zo(25,7)))*ai(2*i(E)),L=Wo(Zo(F/(e*S),2)+Zo(A/(n*N),2)+Zo(I/(a*T),2)+B*(A/(n*N))*(I/(a*T)));return ti(0,Qo(100,L))},ci=k,li=function(t,r,e){void 0===e&&(e="lab"),t=new ci(t),r=new ci(r);var n=t.get(e),a=r.get(e),o=0;for(var i in n){var s=(n[i]||0)-(a[i]||0);o+=s*s}return Math.sqrt(o)},ui=k,fi=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{return new(Function.prototype.bind.apply(ui,[null].concat(t))),!0}catch(t){return!1}},hi=M,di=io,pi={cool:function(){return di([hi.hsl(180,1,.9),hi.hsl(250,.7,.4)])},hot:function(){return di(["#000","#f00","#ff0","#fff"]).mode("rgb")}},gi={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Viridis:["#440154","#482777","#3f4a8a","#31678e","#26838f","#1f9d8a","#6cce5a","#b6de2b","#fee825"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]},bi=0,mi=Object.keys(gi);bi10&&/[0-9](?:\s|\/)/.test(t)&&(n=t.match(/([0-9]+)/g).map((function(t){return parseFloat(t)})),e=t.match(/([a-z])/gi).join("").toLowerCase());else isNaN(t)?Array.isArray(t)||t.length?(n=[t[0],t[1],t[2]],e="rgb",a=4===t.length?t[3]:1):t instanceof Object&&(null!=t.r||null!=t.red||null!=t.R?(e="rgb",n=[t.r||t.red||t.R||0,t.g||t.green||t.G||0,t.b||t.blue||t.B||0]):(e="hsl",n=[t.h||t.hue||t.H||0,t.s||t.saturation||t.S||0,t.l||t.lightness||t.L||t.b||t.brightness]),a=t.a||t.alpha||t.opacity||1,null!=t.opacity&&(a/=100)):(e="rgb",n=[t>>>16,(65280&t)>>>8,255&t]);return{space:e,values:n,alpha:a}},X={red:0,orange:60,yellow:120,green:180,blue:240,purple:300};const J=K;function W(t,r){if(t.space||(t=J(t)),r.space||(r=J(r)),"rgb"!==t.space)throw new Error("First color's space "+t.space+" is not supported.");if("rgb"!==r.space)throw new Error("Second color's space "+r.space+" is not supported.");if(1===t.alpha)return t;if(0===t.alpha)return r;for(var e={space:r.space,values:r.values.slice(),alpha:t.alpha+r.alpha*(1-t.alpha)},n=0;n<3;n++){var a=t.values[n]*t.alpha,o=r.values[n]*r.alpha;e.values[n]=Math.round((a+o*(1-t.alpha))/e.alpha)}return e}var Z={composite:function(t){for(var r=t[0],e=1,n=t.length;e{const{values:[n,a,o]}=tt(Q(t).alpha(e).hex(),r);return`rgb(${n}, ${a}, ${o})`};const et=U,nt=H.exports,at=(t,r,e)=>({hover:rt(r,t,e?.hoverOpacity||.08),press:rt(r,t,e?.pressOpacity||.12),focus:rt(r,t,e?.focusOpacity||.12),drag:rt(r,t,e?.dragOpacity||.16)}),ot={surfacePrefix:"surface",interactiveSurfacePrefix:"interactive-surface",disabledStyles:{textOpacity:.38,backgroundOpacity:.12,colorName:"black"},transition:{duration:150}},it=t=>Object.assign({},...Object.entries(t??{}).flatMap((([t,r])=>"object"==typeof r?Object.entries(it(r)).map((([r,e])=>({[t+("DEFAULT"===r?"":`-${r}`)]:e}))):[{[`${t}`]:r}])));var st={exports:{}},ct={exports:{}},lt=function(t){return!(!t||"string"==typeof t)&&(t instanceof Array||Array.isArray(t)||t.length>=0&&(t.splice instanceof Function||Object.getOwnPropertyDescriptor(t,t.length-1)&&"String"!==t.constructor.name))},ut=Array.prototype.concat,ft=Array.prototype.slice,ht=ct.exports=function(t){for(var r=[],e=0,n=t.length;e=4&&1!==t[3]&&(r=", "+t[3]),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+r+")"},vt.to.keyword=function(t){return bt[t.slice(0,3)]};const wt=G,Mt={};for(const t of Object.keys(wt))Mt[wt[t]]=t;const Ct={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};var Pt=Ct;for(const t of Object.keys(Ct)){if(!("channels"in Ct[t]))throw new Error("missing channels property: "+t);if(!("labels"in Ct[t]))throw new Error("missing channel labels property: "+t);if(Ct[t].labels.length!==Ct[t].channels)throw new Error("channel and label counts mismatch: "+t);const{channels:r,labels:e}=Ct[t];delete Ct[t].channels,delete Ct[t].labels,Object.defineProperty(Ct[t],"channels",{value:r}),Object.defineProperty(Ct[t],"labels",{value:e})}Ct.rgb.hsl=function(t){const r=t[0]/255,e=t[1]/255,n=t[2]/255,a=Math.min(r,e,n),o=Math.max(r,e,n),i=o-a;let s,c;o===a?s=0:r===o?s=(e-n)/i:e===o?s=2+(n-r)/i:n===o&&(s=4+(r-e)/i),s=Math.min(60*s,360),s<0&&(s+=360);const l=(a+o)/2;return c=o===a?0:l<=.5?i/(o+a):i/(2-o-a),[s,100*c,100*l]},Ct.rgb.hsv=function(t){let r,e,n,a,o;const i=t[0]/255,s=t[1]/255,c=t[2]/255,l=Math.max(i,s,c),u=l-Math.min(i,s,c),f=function(t){return(l-t)/6/u+.5};return 0===u?(a=0,o=0):(o=u/l,r=f(i),e=f(s),n=f(c),i===l?a=n-e:s===l?a=1/3+r-n:c===l&&(a=2/3+e-r),a<0?a+=1:a>1&&(a-=1)),[360*a,100*o,100*l]},Ct.rgb.hwb=function(t){const r=t[0],e=t[1];let n=t[2];const a=Ct.rgb.hsl(t)[0],o=1/255*Math.min(r,Math.min(e,n));return n=1-1/255*Math.max(r,Math.max(e,n)),[a,100*o,100*n]},Ct.rgb.cmyk=function(t){const r=t[0]/255,e=t[1]/255,n=t[2]/255,a=Math.min(1-r,1-e,1-n);return[100*((1-r-a)/(1-a)||0),100*((1-e-a)/(1-a)||0),100*((1-n-a)/(1-a)||0),100*a]},Ct.rgb.keyword=function(t){const r=Mt[t];if(r)return r;let e,n=1/0;for(const r of Object.keys(wt)){const i=(o=wt[r],((a=t)[0]-o[0])**2+(a[1]-o[1])**2+(a[2]-o[2])**2);i.04045?((r+.055)/1.055)**2.4:r/12.92,e=e>.04045?((e+.055)/1.055)**2.4:e/12.92,n=n>.04045?((n+.055)/1.055)**2.4:n/12.92;return[100*(.4124*r+.3576*e+.1805*n),100*(.2126*r+.7152*e+.0722*n),100*(.0193*r+.1192*e+.9505*n)]},Ct.rgb.lab=function(t){const r=Ct.rgb.xyz(t);let e=r[0],n=r[1],a=r[2];e/=95.047,n/=100,a/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,n=n>.008856?n**(1/3):7.787*n+16/116,a=a>.008856?a**(1/3):7.787*a+16/116;return[116*n-16,500*(e-n),200*(n-a)]},Ct.hsl.rgb=function(t){const r=t[0]/360,e=t[1]/100,n=t[2]/100;let a,o,i;if(0===e)return i=255*n,[i,i,i];a=n<.5?n*(1+e):n+e-n*e;const s=2*n-a,c=[0,0,0];for(let t=0;t<3;t++)o=r+1/3*-(t-1),o<0&&o++,o>1&&o--,i=6*o<1?s+6*(a-s)*o:2*o<1?a:3*o<2?s+(a-s)*(2/3-o)*6:s,c[t]=255*i;return c},Ct.hsl.hsv=function(t){const r=t[0];let e=t[1]/100,n=t[2]/100,a=e;const o=Math.max(n,.01);n*=2,e*=n<=1?n:2-n,a*=o<=1?o:2-o;return[r,100*(0===n?2*a/(o+a):2*e/(n+e)),100*((n+e)/2)]},Ct.hsv.rgb=function(t){const r=t[0]/60,e=t[1]/100;let n=t[2]/100;const a=Math.floor(r)%6,o=r-Math.floor(r),i=255*n*(1-e),s=255*n*(1-e*o),c=255*n*(1-e*(1-o));switch(n*=255,a){case 0:return[n,c,i];case 1:return[s,n,i];case 2:return[i,n,c];case 3:return[i,s,n];case 4:return[c,i,n];case 5:return[n,i,s]}},Ct.hsv.hsl=function(t){const r=t[0],e=t[1]/100,n=t[2]/100,a=Math.max(n,.01);let o,i;i=(2-e)*n;const s=(2-e)*a;return o=e*a,o/=s<=1?s:2-s,o=o||0,i/=2,[r,100*o,100*i]},Ct.hwb.rgb=function(t){const r=t[0]/360;let e=t[1]/100,n=t[2]/100;const a=e+n;let o;a>1&&(e/=a,n/=a);const i=Math.floor(6*r),s=1-n;o=6*r-i,0!=(1&i)&&(o=1-o);const c=e+o*(s-e);let l,u,f;switch(i){default:case 6:case 0:l=s,u=c,f=e;break;case 1:l=c,u=s,f=e;break;case 2:l=e,u=s,f=c;break;case 3:l=e,u=c,f=s;break;case 4:l=c,u=e,f=s;break;case 5:l=s,u=e,f=c}return[255*l,255*u,255*f]},Ct.cmyk.rgb=function(t){const r=t[0]/100,e=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,r*(1-a)+a)),255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]},Ct.xyz.rgb=function(t){const r=t[0]/100,e=t[1]/100,n=t[2]/100;let a,o,i;return a=3.2406*r+-1.5372*e+-.4986*n,o=-.9689*r+1.8758*e+.0415*n,i=.0557*r+-.204*e+1.057*n,a=a>.0031308?1.055*a**(1/2.4)-.055:12.92*a,o=o>.0031308?1.055*o**(1/2.4)-.055:12.92*o,i=i>.0031308?1.055*i**(1/2.4)-.055:12.92*i,a=Math.min(Math.max(0,a),1),o=Math.min(Math.max(0,o),1),i=Math.min(Math.max(0,i),1),[255*a,255*o,255*i]},Ct.xyz.lab=function(t){let r=t[0],e=t[1],n=t[2];r/=95.047,e/=100,n/=108.883,r=r>.008856?r**(1/3):7.787*r+16/116,e=e>.008856?e**(1/3):7.787*e+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;return[116*e-16,500*(r-e),200*(e-n)]},Ct.lab.xyz=function(t){let r,e,n;e=(t[0]+16)/116,r=t[1]/500+e,n=e-t[2]/200;const a=e**3,o=r**3,i=n**3;return e=a>.008856?a:(e-16/116)/7.787,r=o>.008856?o:(r-16/116)/7.787,n=i>.008856?i:(n-16/116)/7.787,r*=95.047,e*=100,n*=108.883,[r,e,n]},Ct.lab.lch=function(t){const r=t[0],e=t[1],n=t[2];let a;a=360*Math.atan2(n,e)/2/Math.PI,a<0&&(a+=360);return[r,Math.sqrt(e*e+n*n),a]},Ct.lch.lab=function(t){const r=t[0],e=t[1],n=t[2]/360*2*Math.PI;return[r,e*Math.cos(n),e*Math.sin(n)]},Ct.rgb.ansi16=function(t,r=null){const[e,n,a]=t;let o=null===r?Ct.rgb.hsv(t)[2]:r;if(o=Math.round(o/50),0===o)return 30;let i=30+(Math.round(a/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===o&&(i+=60),i},Ct.hsv.ansi16=function(t){return Ct.rgb.ansi16(Ct.hsv.rgb(t),t[2])},Ct.rgb.ansi256=function(t){const r=t[0],e=t[1],n=t[2];if(r===e&&e===n)return r<8?16:r>248?231:Math.round((r-8)/247*24)+232;return 16+36*Math.round(r/255*5)+6*Math.round(e/255*5)+Math.round(n/255*5)},Ct.ansi16.rgb=function(t){let r=t%10;if(0===r||7===r)return t>50&&(r+=3.5),r=r/10.5*255,[r,r,r];const e=.5*(1+~~(t>50));return[(1&r)*e*255,(r>>1&1)*e*255,(r>>2&1)*e*255]},Ct.ansi256.rgb=function(t){if(t>=232){const r=10*(t-232)+8;return[r,r,r]}let r;t-=16;return[Math.floor(t/36)/5*255,Math.floor((r=t%36)/6)/5*255,r%6/5*255]},Ct.rgb.hex=function(t){const r=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(r.length)+r},Ct.hex.rgb=function(t){const r=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!r)return[0,0,0];let e=r[0];3===r[0].length&&(e=e.split("").map((t=>t+t)).join(""));const n=parseInt(e,16);return[n>>16&255,n>>8&255,255&n]},Ct.rgb.hcg=function(t){const r=t[0]/255,e=t[1]/255,n=t[2]/255,a=Math.max(Math.max(r,e),n),o=Math.min(Math.min(r,e),n),i=a-o;let s,c;return s=i<1?o/(1-i):0,c=i<=0?0:a===r?(e-n)/i%6:a===e?2+(n-r)/i:4+(r-e)/i,c/=6,c%=1,[360*c,100*i,100*s]},Ct.hsl.hcg=function(t){const r=t[1]/100,e=t[2]/100,n=e<.5?2*r*e:2*r*(1-e);let a=0;return n<1&&(a=(e-.5*n)/(1-n)),[t[0],100*n,100*a]},Ct.hsv.hcg=function(t){const r=t[1]/100,e=t[2]/100,n=r*e;let a=0;return n<1&&(a=(e-n)/(1-n)),[t[0],100*n,100*a]},Ct.hcg.rgb=function(t){const r=t[0]/360,e=t[1]/100,n=t[2]/100;if(0===e)return[255*n,255*n,255*n];const a=[0,0,0],o=r%1*6,i=o%1,s=1-i;let c=0;switch(Math.floor(o)){case 0:a[0]=1,a[1]=i,a[2]=0;break;case 1:a[0]=s,a[1]=1,a[2]=0;break;case 2:a[0]=0,a[1]=1,a[2]=i;break;case 3:a[0]=0,a[1]=s,a[2]=1;break;case 4:a[0]=i,a[1]=0,a[2]=1;break;default:a[0]=1,a[1]=0,a[2]=s}return c=(1-e)*n,[255*(e*a[0]+c),255*(e*a[1]+c),255*(e*a[2]+c)]},Ct.hcg.hsv=function(t){const r=t[1]/100,e=r+t[2]/100*(1-r);let n=0;return e>0&&(n=r/e),[t[0],100*n,100*e]},Ct.hcg.hsl=function(t){const r=t[1]/100,e=t[2]/100*(1-r)+.5*r;let n=0;return e>0&&e<.5?n=r/(2*e):e>=.5&&e<1&&(n=r/(2*(1-e))),[t[0],100*n,100*e]},Ct.hcg.hwb=function(t){const r=t[1]/100,e=r+t[2]/100*(1-r);return[t[0],100*(e-r),100*(1-e)]},Ct.hwb.hcg=function(t){const r=t[1]/100,e=1-t[2]/100,n=e-r;let a=0;return n<1&&(a=(e-n)/(1-n)),[t[0],100*n,100*a]},Ct.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},Ct.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},Ct.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},Ct.gray.hsl=function(t){return[0,0,t[0]]},Ct.gray.hsv=Ct.gray.hsl,Ct.gray.hwb=function(t){return[0,100,t[0]]},Ct.gray.cmyk=function(t){return[0,0,0,t[0]]},Ct.gray.lab=function(t){return[t[0],0,0]},Ct.gray.hex=function(t){const r=255&Math.round(t[0]/100*255),e=((r<<16)+(r<<8)+r).toString(16).toUpperCase();return"000000".substring(e.length)+e},Ct.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]};const xt=Pt;function _t(t){const r=function(){const t={},r=Object.keys(xt);for(let e=r.length,n=0;n{At[t]={},Object.defineProperty(At[t],"channels",{value:It[t].channels}),Object.defineProperty(At[t],"labels",{value:It[t].labels});const r=Ft(t);Object.keys(r).forEach((e=>{const n=r[e];At[t][e]=function(t){const r=function(...r){const e=r[0];if(null==e)return e;e.length>1&&(r=e);const n=t(r);if("object"==typeof n)for(let t=n.length,r=0;r1&&(r=e),t(r))};return"conversion"in t&&(r.conversion=t.conversion),r}(n)}))}));var St=At;const Nt=st.exports,Tt=St,Et=["keyword","gray","hex"],Bt={};for(const t of Object.keys(Tt))Bt[[...Tt[t].labels].sort().join("")]=t;const Lt={};function jt(t,r){if(!(this instanceof jt))return new jt(t,r);if(r&&r in Et&&(r=null),r&&!(r in Tt))throw new Error("Unknown model: "+r);let e,n;if(null==t)this.model="rgb",this.color=[0,0,0],this.valpha=1;else if(t instanceof jt)this.model=t.model,this.color=[...t.color],this.valpha=t.valpha;else if("string"==typeof t){const r=Nt.get(t);if(null===r)throw new Error("Unable to parse color from string: "+t);this.model=r.model,n=Tt[this.model].channels,this.color=r.value.slice(0,n),this.valpha="number"==typeof r.value[n]?r.value[n]:1}else if(t.length>0){this.model=r||"rgb",n=Tt[this.model].channels;const e=Array.prototype.slice.call(t,0,n);this.color=qt(e,n),this.valpha="number"==typeof t[n]?t[n]:1}else if("number"==typeof t)this.model="rgb",this.color=[t>>16&255,t>>8&255,255&t],this.valpha=1;else{this.valpha=1;const r=Object.keys(t);"alpha"in t&&(r.splice(r.indexOf("alpha"),1),this.valpha="number"==typeof t.alpha?t.alpha:0);const n=r.sort().join("");if(!(n in Bt))throw new Error("Unable to parse color from object: "+JSON.stringify(t));this.model=Bt[n];const{labels:a}=Tt[this.model],o=[];for(e=0;e(t%360+360)%360)),saturationl:$t("hsl",1,Vt(100)),lightness:$t("hsl",2,Vt(100)),saturationv:$t("hsv",1,Vt(100)),value:$t("hsv",2,Vt(100)),chroma:$t("hcg",1,Vt(100)),gray:$t("hcg",2,Vt(100)),white:$t("hwb",1,Vt(100)),wblack:$t("hwb",2,Vt(100)),cyan:$t("cmyk",0,Vt(100)),magenta:$t("cmyk",1,Vt(100)),yellow:$t("cmyk",2,Vt(100)),black:$t("cmyk",3,Vt(100)),x:$t("xyz",0,Vt(95.047)),y:$t("xyz",1,Vt(100)),z:$t("xyz",2,Vt(108.833)),l:$t("lab",0,Vt(100)),a:$t("lab",1),b:$t("lab",2),keyword(t){return void 0!==t?new jt(t):Tt[this.model].keyword(this.color)},hex(t){return void 0!==t?new jt(t):Nt.to.hex(this.rgb().round().color)},hexa(t){if(void 0!==t)return new jt(t);const r=this.rgb().round().color;let e=Math.round(255*this.valpha).toString(16).toUpperCase();return 1===e.length&&(e="0"+e),Nt.to.hex(r)+e},rgbNumber(){const t=this.rgb().color;return(255&t[0])<<16|(255&t[1])<<8|255&t[2]},luminosity(){const t=this.rgb().color,r=[];for(const[e,n]of t.entries()){const t=n/255;r[e]=t<=.04045?t/12.92:((t+.055)/1.055)**2.4}return.2126*r[0]+.7152*r[1]+.0722*r[2]},contrast(t){const r=this.luminosity(),e=t.luminosity();return r>e?(r+.05)/(e+.05):(e+.05)/(r+.05)},level(t){const r=this.contrast(t);return r>=7?"AAA":r>=4.5?"AA":""},isDark(){const t=this.rgb().color;return(2126*t[0]+7152*t[1]+722*t[2])/1e4<128},isLight(){return!this.isDark()},negate(){const t=this.rgb();for(let r=0;r<3;r++)t.color[r]=255-t.color[r];return t},lighten(t){const r=this.hsl();return r.color[2]+=r.color[2]*t,r},darken(t){const r=this.hsl();return r.color[2]-=r.color[2]*t,r},saturate(t){const r=this.hsl();return r.color[1]+=r.color[1]*t,r},desaturate(t){const r=this.hsl();return r.color[1]-=r.color[1]*t,r},whiten(t){const r=this.hwb();return r.color[1]+=r.color[1]*t,r},blacken(t){const r=this.hwb();return r.color[2]+=r.color[2]*t,r},grayscale(){const t=this.rgb().color,r=.3*t[0]+.59*t[1]+.11*t[2];return jt.rgb(r,r,r)},fade(t){return this.alpha(this.valpha-this.valpha*t)},opaquer(t){return this.alpha(this.valpha+this.valpha*t)},rotate(t){const r=this.hsl();let e=r.color[0];return e=(e+t)%360,e=e<0?360+e:e,r.color[0]=e,r},mix(t,r){if(!t||!t.rgb)throw new Error('Argument to "mix" was not a Color instance, but rather an instance of '+typeof t);const e=t.rgb(),n=this.rgb(),a=void 0===r?.5:r,o=2*a-1,i=e.alpha()-n.alpha(),s=((o*i==-1?o:(o+i)/(1+o*i))+1)/2,c=1-s;return jt.rgb(s*e.red()+c*n.red(),s*e.green()+c*n.green(),s*e.blue()+c*n.blue(),e.alpha()*a+n.alpha()*(1-a))}};for(const t of Object.keys(Tt)){if(Et.includes(t))continue;const{channels:r}=Tt[t];jt.prototype[t]=function(...r){return this.model===t?new jt(this):r.length>0?new jt(r,t):new jt([...(e=Tt[this.model][t].raw(this.color),Array.isArray(e)?e:[e]),this.valpha],t);var e},jt[t]=function(...e){let n=e[0];return"number"==typeof n&&(n=qt(e,r)),new jt(n,t)}}function Rt(t){return function(r){return function(t,r){return Number(t.toFixed(r))}(r,t)}}function $t(t,r,e){t=Array.isArray(t)?t:[t];for(const n of t)(Lt[n]||(Lt[n]=[]))[r]=e;return t=t[0],function(n){let a;return void 0!==n?(e&&(n=e(n)),a=this[t](),a.color[r]=n,a):(a=this[t]().color[r],e&&(a=e(a)),a)}}function Vt(t){return function(r){return Math.max(0,Math.min(t,r))}}function qt(t,r){for(let e=0;eObject.assign({},...Object.entries(t??{}).flatMap((([t,r])=>"object"==typeof r?Object.entries(Ht(r)).map((([r,e])=>({[t+("DEFAULT"===r?"":`-${r}`)]:e}))):[{[`${t}`]:r}])));const Gt=(t,r,e={extend:!1})=>{if(r.primary){const n=V(r);return(t=>{const r=!t.theme.colors,e=Ht(r?t.theme.extend.colors||{}:t.theme.colors),n=Array.isArray(t.darkMode)?"class"!==t.darkMode[0]:"class"!==t.darkMode,a=!n&&(Array.isArray(t.darkMode)&&t.darkMode[1]||".dark"),o={html:{},...n?{"@media (prefers-color-scheme: dark)":{html:{}}}:{[a]:{}}};return Object.keys(e).forEach((t=>{const r=t.match(new RegExp(/^(?:(.+)-)?light(?:-(.+))?$/));if(r){const i=r[1],s=r[2],c=[i,s].filter((t=>t)).join("-"),l=e[t],u=e[[i,"dark",s].filter((t=>t)).join("-")];if(l&&u){if(e[c])throw`withModeAwareColors plugin error: adding the '${c}' mode-aware color would overwrite an existing color.`;{const t=`--color-${c}`;e[c]=`rgb(var(${t}) / )`;const r=Ut(l).rgb().array().join(" "),i=Ut(u).rgb().array().join(" ");o.html[t]=r,n?o["@media (prefers-color-scheme: dark)"].html[t]=i:o[a][t]=i}}}})),{...t,theme:r?{...t.theme,extend:{...t.theme.extend||{},colors:e}}:{...t.theme||[],colors:e},plugins:[...t.plugins||[],zt((({addBase:t})=>t(o)))]}})(((t,r={})=>{const{surfacePrefix:e,interactiveSurfacePrefix:n,disabledStyles:a,transition:o}={...ot,...r},i=!t.theme.colors,s=it(i?t.theme.extend.colors||{}:t.theme.colors);return Object.keys(s).forEach((t=>{const e=`on-${t}`,n=s[t],a=s[e];if(!t.startsWith("on-")&&nt.valid(n)&&nt.valid(a)){const e=at(n,a,r);s[`${t}-hover`]=e.hover,s[`${t}-press`]=e.press,s[`${t}-focus`]=e.focus,s[`${t}-drag`]=e.drag}})),{...t,theme:i?{...t.theme,extend:{...t.theme.extend||{},colors:s}}:{...t.theme||[],colors:s},plugins:[...t.plugins||[],et((({addComponents:t,theme:r})=>{const i=it(r("colors")||{}),s=Object.keys(i).filter((t=>i[`on-${t}`]&&i[`${t}-hover`]&&i[`${t}-focus`]&&i[`${t}-press`]));let c={};s.forEach((t=>{c[`.${e}-${t}`]={..."bg"===e?{}:{[`@apply bg-${t}`]:{}},[`@apply text-on-${t}`]:{}},c[`.${n}-${t}`]={[`@apply bg-${t}`]:{},[`@apply text-on-${t}`]:{},[`@apply hover:bg-${t}-hover`]:{},[`@apply active:bg-${t}-press`]:{},[`@apply focus-visible:bg-${t}-focus`]:{},...o?{"@apply transition-colors":{},[`@apply duration-${o.duration}`]:{}}:{},...a?{[`@apply disabled:text-${a.colorName}/[${a.textOpacity}]`]:{},[`@apply disabled:bg-${a.colorName}/[${a.backgroundOpacity}]`]:{}}:{}}})),t(c)}),{})]}})({...t,theme:e.extend?{...t.theme||{},extend:{...t.theme?.extend||{},colors:{...t.theme?.extend?.colors||{},...n}}}:{...t.theme||{},colors:{...t.theme?.colors||{},...n}}},{surfacePrefix:"bg",interactiveSurfacePrefix:"interactive-bg",disabledStyles:{textOpacity:.38,backgroundOpacity:.12,colorName:"on-surface"}}))}throw"A primary color must be specified"};export{Gt as withMaterialColors}; -//# sourceMappingURL=index.esm.js.map diff --git a/src/TabKeeper.UI.Wasm/tailwind.config.js b/src/TabKeeper.UI.Wasm/tailwind.config.js index 302290b..4047b33 100644 --- a/src/TabKeeper.UI.Wasm/tailwind.config.js +++ b/src/TabKeeper.UI.Wasm/tailwind.config.js @@ -1,33 +1,38 @@ -const { withMaterialColors } = require('./tailwind-material-colors.esm'); +import { variants } from "./tailwind.config.variants" +import { withMaterialColors } from "./tailwind.config.tailwind-material-colors" module.exports = withMaterialColors( { - darkMode: 'class', + darkMode: ["selector", "[dark]"], content: [ "./**/*.{razor,html,cshtml}" ], + safelist: [ + { pattern: /preference-+/ } + ], plugins: [ - require('@tailwindcss/forms')({ strategy: 'base' }), - require('@tailwindcss/typography') + require("@tailwindcss/typography"), + require("@tailwindcss/forms"), + variants, ], theme: { extend: { - screens: {}, // '2xl': {'max': '1535px'} + screens: {}, // "2xl": {"max": "1535px"} } - }, - safelist: [ - 'material-group' - ] + } }, { - // Here, your base colors as HEX values - // primary is required - primary: '#ff0000', - // secondary and/or tertiary are optional, if not set they will be derived from the primary color - //secondary: '#ffff00', - //tertiary: '#0000ff' + primary: "#E6E6FA", + //secondary: "#005A6F", + //tertiary: "#054C6C", + //error: "#D4352F", + //neutral: "#919094" }, { + /* one of 'content', 'expressive', 'fidelity', 'monochrome', 'neutral', 'tonalSpot' or 'vibrant' */ + scheme: "expressive", + // contrast is optional and ranges from -1 (less contrast) to 1 (more contrast). + contrast: 0, extend: true } ); diff --git a/src/TabKeeper.UI.Wasm/tailwind.config.tailwind-material-colors.js b/src/TabKeeper.UI.Wasm/tailwind.config.tailwind-material-colors.js new file mode 100644 index 0000000..b0c7607 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/tailwind.config.tailwind-material-colors.js @@ -0,0 +1,440 @@ +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +function t(t){return t<0?-1:0===t?0:1}function e(t,e,r){return(1-r)*t+r*e}function r(t,e,r){return re?e:r}function n(t){return(t%=360)<0&&(t+=360),t}function a(t){return(t%=360)<0&&(t+=360),t}function o(t,e){return[t[0]*e[0][0]+t[1]*e[0][1]+t[2]*e[0][2],t[0]*e[1][0]+t[1]*e[1][1]+t[2]*e[1][2],t[0]*e[2][0]+t[1]*e[2][1]+t[2]*e[2][2]]} +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */const i=[[.41233895,.35762064,.18051042],[.2126,.7152,.0722],[.01932141,.11916382,.95034478]],s=[[3.2413774792388685,-1.5376652402851851,-.49885366846268053],[-.9691452513005321,1.8758853451067872,.04156585616912061],[.05562093689691305,-.20395524564742123,1.0571799111220335]],c=[95.047,100,108.883];function l(t,e,r){return(255<<24|(255&t)<<16|(255&e)<<8|255&r)>>>0}function u(t){return l(y(t[0]),y(t[1]),y(t[2]))}function h(t){return t>>16&255}function d(t){return t>>8&255}function m(t){return 255&t}function f(t){const e=function(t){return o([b(h(t)),b(d(t)),b(m(t))],i)}(t)[1];return 116*k(e/100)-16}function g(t){return 100*function(t){const e=24389/27,r=t*t*t;return r>216/24389?r:(116*t-16)/e} +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */((t+16)/116)}function p(t){return 116*k(t/100)-16}function b(t){const e=t/255;return e<=.040449936?e/12.92*100:100*Math.pow((e+.055)/1.055,2.4)}function y(t){const e=t/100;let r=0;return r=e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055,n=0,a=255,(o=Math.round(255*r))a?a:o;var n,a,o}function k(t){return t>216/24389?Math.pow(t,1/3):(903.2962962962963*t+16)/116}class w{static make(t=function(){return c}(),r=200/Math.PI*g(50)/100,n=50,a=2,o=!1){const i=t,s=.401288*i[0]+.650173*i[1]+-.051461*i[2],l=-.250268*i[0]+1.204414*i[1]+.045854*i[2],u=-.002079*i[0]+.048952*i[1]+.953127*i[2],h=.8+a/10,d=h>=.9?e(.59,.69,10*(h-.9)):e(.525,.59,10*(h-.8));let m=o?1:h*(1-1/3.6*Math.exp((-r-42)/92));m=m>1?1:m<0?0:m;const f=h,p=[m*(100/s)+1-m,m*(100/l)+1-m,m*(100/u)+1-m],b=1/(5*r+1),y=b*b*b*b,k=1-y,v=y*r+.1*k*k*Math.cbrt(5*r),M=g(n)/t[1],C=1.48+Math.sqrt(M),P=.725/Math.pow(M,.2),x=P,I=[Math.pow(v*p[0]*s/100,.42),Math.pow(v*p[1]*l/100,.42),Math.pow(v*p[2]*u/100,.42)],D=[400*I[0]/(I[0]+27.13),400*I[1]/(I[1]+27.13),400*I[2]/(I[2]+27.13)];return new w(M,(2*D[0]+D[1]+.05*D[2])*P,P,x,d,f,p,v,Math.pow(v,.25),C)}constructor(t,e,r,n,a,o,i,s,c,l){this.n=t,this.aw=e,this.nbb=r,this.ncb=n,this.c=a,this.nc=o,this.rgbD=i,this.fl=s,this.fLRoot=c,this.z=l}}w.DEFAULT=w.make(); +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class v{constructor(t,e,r,n,a,o,i,s,c){this.hue=t,this.chroma=e,this.j=r,this.q=n,this.m=a,this.s=o,this.jstar=i,this.astar=s,this.bstar=c}distance(t){const e=this.jstar-t.jstar,r=this.astar-t.astar,n=this.bstar-t.bstar,a=Math.sqrt(e*e+r*r+n*n);return 1.41*Math.pow(a,.63)}static fromInt(t){return v.fromIntInViewingConditions(t,w.DEFAULT)}static fromIntInViewingConditions(e,r){const n=(65280&e)>>8,a=255&e,o=b((16711680&e)>>16),i=b(n),s=b(a),c=.41233895*o+.35762064*i+.18051042*s,l=.2126*o+.7152*i+.0722*s,u=.01932141*o+.11916382*i+.95034478*s,h=.401288*c+.650173*l-.051461*u,d=-.250268*c+1.204414*l+.045854*u,m=-.002079*c+.048952*l+.953127*u,f=r.rgbD[0]*h,g=r.rgbD[1]*d,p=r.rgbD[2]*m,y=Math.pow(r.fl*Math.abs(f)/100,.42),k=Math.pow(r.fl*Math.abs(g)/100,.42),w=Math.pow(r.fl*Math.abs(p)/100,.42),M=400*t(f)*y/(y+27.13),C=400*t(g)*k/(k+27.13),P=400*t(p)*w/(w+27.13),x=(11*M+-12*C+P)/11,I=(M+C-2*P)/9,D=(20*M+20*C+21*P)/20,A=(40*M+20*C+P)/20,_=180*Math.atan2(I,x)/Math.PI,O=_<0?_+360:_>=360?_-360:_,S=O*Math.PI/180,T=A*r.nbb,B=100*Math.pow(T/r.aw,r.c*r.z),H=4/r.c*Math.sqrt(B/100)*(r.aw+4)*r.fLRoot,$=O<20.14?O+360:O,F=5e4/13*(.25*(Math.cos($*Math.PI/180+2)+3.8))*r.nc*r.ncb*Math.sqrt(x*x+I*I)/(D+.305),j=Math.pow(F,.9)*Math.pow(1.64-Math.pow(.29,r.n),.73),L=j*Math.sqrt(B/100),R=L*r.fLRoot,E=50*Math.sqrt(j*r.c/(r.aw+4)),V=(1+100*.007)*B/(1+.007*B),N=1/.0228*Math.log(1+.0228*R),q=N*Math.cos(S),z=N*Math.sin(S);return new v(O,L,B,H,R,E,V,q,z)}static fromJch(t,e,r){return v.fromJchInViewingConditions(t,e,r,w.DEFAULT)}static fromJchInViewingConditions(t,e,r,n){const a=4/n.c*Math.sqrt(t/100)*(n.aw+4)*n.fLRoot,o=e*n.fLRoot,i=e/Math.sqrt(t/100),s=50*Math.sqrt(i*n.c/(n.aw+4)),c=r*Math.PI/180,l=(1+100*.007)*t/(1+.007*t),u=1/.0228*Math.log(1+.0228*o),h=u*Math.cos(c),d=u*Math.sin(c);return new v(r,e,t,a,o,s,l,h,d)}static fromUcs(t,e,r){return v.fromUcsInViewingConditions(t,e,r,w.DEFAULT)}static fromUcsInViewingConditions(t,e,r,n){const a=e,o=r,i=Math.sqrt(a*a+o*o),s=(Math.exp(.0228*i)-1)/.0228/n.fLRoot;let c=Math.atan2(o,a)*(180/Math.PI);c<0&&(c+=360);const l=t/(1-.007*(t-100));return v.fromJchInViewingConditions(l,s,c,n)}toInt(){return this.viewed(w.DEFAULT)}viewed(e){const r=0===this.chroma||0===this.j?0:this.chroma/Math.sqrt(this.j/100),n=Math.pow(r/Math.pow(1.64-Math.pow(.29,e.n),.73),1/.9),a=this.hue*Math.PI/180,o=.25*(Math.cos(a+2)+3.8),i=e.aw*Math.pow(this.j/100,1/e.c/e.z),c=o*(5e4/13)*e.nc*e.ncb,u=i/e.nbb,h=Math.sin(a),d=Math.cos(a),m=23*(u+.305)*n/(23*c+11*n*d+108*n*h),f=m*d,g=m*h,p=(460*u+451*f+288*g)/1403,b=(460*u-891*f-261*g)/1403,k=(460*u-220*f-6300*g)/1403,w=Math.max(0,27.13*Math.abs(p)/(400-Math.abs(p))),v=t(p)*(100/e.fl)*Math.pow(w,1/.42),M=Math.max(0,27.13*Math.abs(b)/(400-Math.abs(b))),C=t(b)*(100/e.fl)*Math.pow(M,1/.42),P=Math.max(0,27.13*Math.abs(k)/(400-Math.abs(k))),x=t(k)*(100/e.fl)*Math.pow(P,1/.42),I=v/e.rgbD[0],D=C/e.rgbD[1],A=x/e.rgbD[2],_=function(t,e,r){const n=s,a=n[0][0]*t+n[0][1]*e+n[0][2]*r,o=n[1][0]*t+n[1][1]*e+n[1][2]*r,i=n[2][0]*t+n[2][1]*e+n[2][2]*r;return l(y(a),y(o),y(i))}(1.86206786*I-1.01125463*D+.14918677*A,.38752654*I+.62144744*D-.00897398*A,-.0158415*I-.03412294*D+1.04996444*A);return _}static fromXyzInViewingConditions(e,r,n,a){const o=.401288*e+.650173*r-.051461*n,i=-.250268*e+1.204414*r+.045854*n,s=-.002079*e+.048952*r+.953127*n,c=a.rgbD[0]*o,l=a.rgbD[1]*i,u=a.rgbD[2]*s,h=Math.pow(a.fl*Math.abs(c)/100,.42),d=Math.pow(a.fl*Math.abs(l)/100,.42),m=Math.pow(a.fl*Math.abs(u)/100,.42),f=400*t(c)*h/(h+27.13),g=400*t(l)*d/(d+27.13),p=400*t(u)*m/(m+27.13),b=(11*f+-12*g+p)/11,y=(f+g-2*p)/9,k=(20*f+20*g+21*p)/20,w=(40*f+20*g+p)/20,M=180*Math.atan2(y,b)/Math.PI,C=M<0?M+360:M>=360?M-360:M,P=C*Math.PI/180,x=w*a.nbb,I=100*Math.pow(x/a.aw,a.c*a.z),D=4/a.c*Math.sqrt(I/100)*(a.aw+4)*a.fLRoot,A=C<20.14?C+360:C,_=5e4/13*(1/4*(Math.cos(A*Math.PI/180+2)+3.8))*a.nc*a.ncb*Math.sqrt(b*b+y*y)/(k+.305),O=Math.pow(_,.9)*Math.pow(1.64-Math.pow(.29,a.n),.73),S=O*Math.sqrt(I/100),T=S*a.fLRoot,B=50*Math.sqrt(O*a.c/(a.aw+4)),H=(1+100*.007)*I/(1+.007*I),$=Math.log(1+.0228*T)/.0228,F=$*Math.cos(P),j=$*Math.sin(P);return new v(C,S,I,D,T,B,H,F,j)}xyzInViewingConditions(e){const r=0===this.chroma||0===this.j?0:this.chroma/Math.sqrt(this.j/100),n=Math.pow(r/Math.pow(1.64-Math.pow(.29,e.n),.73),1/.9),a=this.hue*Math.PI/180,o=.25*(Math.cos(a+2)+3.8),i=e.aw*Math.pow(this.j/100,1/e.c/e.z),s=o*(5e4/13)*e.nc*e.ncb,c=i/e.nbb,l=Math.sin(a),u=Math.cos(a),h=23*(c+.305)*n/(23*s+11*n*u+108*n*l),d=h*u,m=h*l,f=(460*c+451*d+288*m)/1403,g=(460*c-891*d-261*m)/1403,p=(460*c-220*d-6300*m)/1403,b=Math.max(0,27.13*Math.abs(f)/(400-Math.abs(f))),y=t(f)*(100/e.fl)*Math.pow(b,1/.42),k=Math.max(0,27.13*Math.abs(g)/(400-Math.abs(g))),w=t(g)*(100/e.fl)*Math.pow(k,1/.42),v=Math.max(0,27.13*Math.abs(p)/(400-Math.abs(p))),M=t(p)*(100/e.fl)*Math.pow(v,1/.42),C=y/e.rgbD[0],P=w/e.rgbD[1],x=M/e.rgbD[2];return[1.86206786*C-1.01125463*P+.14918677*x,.38752654*C+.62144744*P-.00897398*x,-.0158415*C-.03412294*P+1.04996444*x]}} +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class M{static sanitizeRadians(t){return(t+8*Math.PI)%(2*Math.PI)}static trueDelinearized(t){const e=t/100;let r=0;return r=e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055,255*r}static chromaticAdaptation(e){const r=Math.pow(Math.abs(e),.42);return 400*t(e)*r/(r+27.13)}static hueOf(t){const e=o(t,M.SCALED_DISCOUNT_FROM_LINRGB),r=M.chromaticAdaptation(e[0]),n=M.chromaticAdaptation(e[1]),a=M.chromaticAdaptation(e[2]),i=(11*r+-12*n+a)/11,s=(r+n-2*a)/9;return Math.atan2(s,i)}static areInCyclicOrder(t,e,r){return M.sanitizeRadians(e-t)100.01||v[1]>100.01||v[2]>100.01?0:u(v);n-=(I-r)*n/(2*I)}return 0}static solveToInt(t,e,r){if(e<1e-4||r<1e-4||r>99.9999)return function(t){const e=y(g(t));return l(e,e,e)}(r);const n=(t=a(t))/180*Math.PI,o=g(r),i=M.findResultByJ(n,e,o);if(0!==i)return i;return u(M.bisectToLimit(o,n))}static solveToCam(t,e,r){return v.fromInt(M.solveToInt(t,e,r))}}M.SCALED_DISCOUNT_FROM_LINRGB=[[.001200833568784504,.002389694492170889,.0002795742885861124],[.0005891086651375999,.0029785502573438758,.0003270666104008398],[.00010146692491640572,.0005364214359186694,.0032979401770712076]],M.LINRGB_FROM_SCALED_DISCOUNT=[[1373.2198709594231,-1100.4251190754821,-7.278681089101213],[-271.815969077903,559.6580465940733,-32.46047482791194],[1.9622899599665666,-57.173814538844006,308.7233197812385]],M.Y_FROM_LINRGB=[.2126,.7152,.0722],M.CRITICAL_PLANES=[.015176349177441876,.045529047532325624,.07588174588720938,.10623444424209313,.13658714259697685,.16693984095186062,.19729253930674434,.2276452376616281,.2579979360165119,.28835063437139563,.3188300904430532,.350925934958123,.3848314933096426,.42057480301049466,.458183274052838,.4976837250274023,.5391024159806381,.5824650784040898,.6277969426914107,.6751227633498623,.7244668422128921,.775853049866786,.829304845476233,.8848452951698498,.942497089126609,1.0022825574869039,1.0642236851973577,1.1283421258858297,1.1946592148522128,1.2631959812511864,1.3339731595349034,1.407011200216447,1.4823302800086415,1.5599503113873272,1.6398909516233677,1.7221716113234105,1.8068114625156377,1.8938294463134073,1.9832442801866852,2.075074464868551,2.1693382909216234,2.2660538449872063,2.36523901573795,2.4669114995532007,2.5710888059345764,2.6777882626779785,2.7870270208169257,2.898822059350997,3.0131901897720907,3.1301480604002863,3.2497121605402226,3.3718988244681087,3.4967242352587946,3.624204428461639,3.754355295633311,3.887192587735158,4.022731918402185,4.160988767090289,4.301978482107941,4.445716283538092,4.592217266055746,4.741496401646282,4.893568542229298,5.048448422192488,5.20615066083972,5.3666897647573375,5.5300801301023865,5.696336044816294,5.865471690767354,6.037501145825082,6.212438385869475,6.390297286737924,6.571091626112461,6.7548350853498045,6.941541251256611,7.131223617812143,7.323895587840543,7.5195704746346665,7.7182615035334345,7.919981813454504,8.124744458384042,8.332562408825165,8.543448553206703,8.757415699253682,8.974476575321063,9.194643831691977,9.417930041841839,9.644347703669503,9.873909240696694,10.106627003236781,10.342513269534024,10.58158024687427,10.8238400726681,11.069304815507364,11.317986476196008,11.569896988756009,11.825048221409341,12.083451977536606,12.345119996613247,12.610063955123938,12.878295467455942,13.149826086772048,13.42466730586372,13.702830557985108,13.984327217668513,14.269168601521828,14.55736596900856,14.848930523210871,15.143873411576273,15.44220572664832,15.743938506781891,16.04908273684337,16.35764934889634,16.66964922287304,16.985093187232053,17.30399201960269,17.62635644741625,17.95219714852476,18.281524751807332,18.614349837764564,18.95068293910138,19.290534541298456,19.633915083172692,19.98083495742689,20.331304511189067,20.685334046541502,21.042933821039977,21.404114048223256,21.76888489811322,22.137256497705877,22.50923893145328,22.884842241736916,23.264076429332462,23.6469514538663,24.033477234264016,24.42366364919083,24.817520537484558,25.21505769858089,25.61628489293138,26.021211842414342,26.429848230738664,26.842203703840827,27.258287870275353,27.678110301598522,28.10168053274597,28.529008062403893,28.96010235337422,29.39497283293396,29.83362889318845,30.276079891419332,30.722335150426627,31.172403958865512,31.62629557157785,32.08401920991837,32.54558406207592,33.010999283389665,33.4802739966603,33.953417292456834,34.430438229418264,34.911345834551085,35.39614910352207,35.88485700094671,36.37747846067349,36.87402238606382,37.37449765026789,37.87891309649659,38.38727753828926,38.89959975977785,39.41588851594697,39.93615253289054,40.460400508064545,40.98864111053629,41.520882981230194,42.05713473317016,42.597404951718396,43.141702194811224,43.6900349931913,44.24241185063697,44.798841244188324,45.35933162437017,45.92389141541209,46.49252901546552,47.065252796817916,47.64207110610409,48.22299226451468,48.808024568002054,49.3971762874833,49.9904556690408,50.587870934119984,51.189430279724725,51.79514187861014,52.40501387947288,53.0190544071392,53.637271562750364,54.259673423945976,54.88626804504493,55.517063457223934,56.15206766869424,56.79128866487574,57.43473440856916,58.08241284012621,58.734331877617365,59.39049941699807,60.05092333227251,60.715611475655585,61.38457167773311,62.057811747619894,62.7353394731159,63.417162620860914,64.10328893648692,64.79372614476921,65.48848194977529,66.18756403501224,66.89098006357258,67.59873767827808,68.31084450182222,69.02730813691093,69.74813616640164,70.47333615344107,71.20291564160104,71.93688215501312,72.67524319850172,73.41800625771542,74.16517879925733,74.9167682708136,75.67278210128072,76.43322770089146,77.1981124613393,77.96744375590167,78.74122893956174,79.51947534912904,80.30219030335869,81.08938110306934,81.88105503125999,82.67721935322541,83.4778813166706,84.28304815182372,85.09272707154808,85.90692527145302,86.72564993000343,87.54890820862819,88.3767072518277,89.2090541872801,90.04595612594655,90.88742016217518,91.73345337380438,92.58406282226491,93.43925555268066,94.29903859396902,95.16341895893969,96.03240364439274,96.9059996312159,97.78421388448044,98.6670533535366,99.55452497210776]; +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class C{static from(t,e,r){return new C(M.solveToInt(t,e,r))}static fromInt(t){return new C(t)}toInt(){return this.argb}get hue(){return this.internalHue}set hue(t){this.setInternalState(M.solveToInt(t,this.internalChroma,this.internalTone))}get chroma(){return this.internalChroma}set chroma(t){this.setInternalState(M.solveToInt(this.internalHue,t,this.internalTone))}get tone(){return this.internalTone}set tone(t){this.setInternalState(M.solveToInt(this.internalHue,this.internalChroma,t))}constructor(t){this.argb=t;const e=v.fromInt(t);this.internalHue=e.hue,this.internalChroma=e.chroma,this.internalTone=f(t),this.argb=t}setInternalState(t){const e=v.fromInt(t);this.internalHue=e.hue,this.internalChroma=e.chroma,this.internalTone=f(t),this.argb=t}inViewingConditions(t){const e=v.fromInt(this.toInt()).xyzInViewingConditions(t),r=v.fromXyzInViewingConditions(e[0],e[1],e[2],w.make());return C.from(r.hue,r.chroma,p(e[1]))}} +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class P{static harmonize(t,e){const r=C.fromInt(t),n=C.fromInt(e),o=(i=r.hue,s=n.hue,180-Math.abs(Math.abs(i-s)-180));var i,s;const c=Math.min(.5*o,15),l=a(r.hue+c*(u=r.hue,a(n.hue-u)<=180?1:-1));var u;return C.from(l,r.chroma,r.tone).toInt()}static hctHue(t,e,r){const n=P.cam16Ucs(t,e,r),a=v.fromInt(n),o=v.fromInt(t);return C.from(a.hue,o.chroma,f(t)).toInt()}static cam16Ucs(t,e,r){const n=v.fromInt(t),a=v.fromInt(e),o=n.jstar,i=n.astar,s=n.bstar,c=o+(a.jstar-o)*r,l=i+(a.astar-i)*r,u=s+(a.bstar-s)*r;return v.fromUcs(c,l,u).toInt()}} +/** + * @license + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class x{static ratioOfTones(t,e){return t=r(0,100,t),e=r(0,100,e),x.ratioOfYs(g(t),g(e))}static ratioOfYs(t,e){const r=t>e?t:e;return(r+5)/((r===e?t:e)+5)}static lighter(t,e){if(t<0||t>100)return-1;const r=g(t),n=e*(r+5)-5,a=x.ratioOfYs(n,r),o=Math.abs(a-e);if(a.04)return-1;const i=p(n)+.4;return i<0||i>100?-1:i}static darker(t,e){if(t<0||t>100)return-1;const r=g(t),n=(r+5)/e-5,a=x.ratioOfYs(r,n),o=Math.abs(a-e);if(a.04)return-1;const i=p(n)-.4;return i<0||i>100?-1:i}static lighterUnsafe(t,e){const r=x.lighter(t,e);return r<0?100:r}static darkerUnsafe(t,e){const r=x.darker(t,e);return r<0?0:r}} +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class I{static isDisliked(t){const e=Math.round(t.hue)>=90&&Math.round(t.hue)<=111,r=Math.round(t.chroma)>16,n=Math.round(t.tone)<65;return e&&r&&n}static fixIfDisliked(t){return I.isDisliked(t)?C.from(t.hue,t.chroma,70):t}} +/** + * @license + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class D{static fromPalette(t){return new D(t.name??"",t.palette,t.tone,t.isBackground??!1,t.background,t.secondBackground,t.contrastCurve,t.toneDeltaPair)}constructor(t,e,r,n,a,o,i,s){if(this.name=t,this.palette=e,this.tone=r,this.isBackground=n,this.background=a,this.secondBackground=o,this.contrastCurve=i,this.toneDeltaPair=s,this.hctCache=new Map,!a&&o)throw new Error(`Color ${t} has secondBackgrounddefined, but background is not defined.`);if(!a&&i)throw new Error(`Color ${t} has contrastCurvedefined, but background is not defined.`);if(a&&!i)throw new Error(`Color ${t} has backgrounddefined, but contrastCurve is not defined.`)}getArgb(t){return this.getHct(t).toInt()}getHct(t){const e=this.hctCache.get(t);if(null!=e)return e;const r=this.getTone(t),n=this.palette(t).getHct(r);return this.hctCache.size>4&&this.hctCache.clear(),this.hctCache.set(t,n),n}getTone(t){const e=t.contrastLevel<0;if(this.toneDeltaPair){const n=this.toneDeltaPair(t),a=n.roleA,o=n.roleB,i=n.delta,s=n.polarity,c=n.stayTogether,l=this.background(t).getTone(t),u="nearer"===s||"lighter"===s&&!t.isDark||"darker"===s&&t.isDark,h=u?a:o,d=u?o:a,m=this.name===h.name,f=t.isDark?1:-1,g=h.contrastCurve.getContrast(t.contrastLevel),p=d.contrastCurve.getContrast(t.contrastLevel),b=h.tone(t);let y=x.ratioOfTones(l,b)>=g?b:D.foregroundTone(l,g);const k=d.tone(t);let w=x.ratioOfTones(l,k)>=p?k:D.foregroundTone(l,p);return e&&(y=D.foregroundTone(l,g),w=D.foregroundTone(l,p)),(w-y)*f>=i||(w=r(0,100,y+i*f),(w-y)*f>=i||(y=r(0,100,w-i*f))),50<=y&&y<60?f>0?(y=60,w=Math.max(w,y+i*f)):(y=49,w=Math.min(w,y+i*f)):50<=w&&w<60&&(c?f>0?(y=60,w=Math.max(w,y+i*f)):(y=49,w=Math.min(w,y+i*f)):w=f>0?60:49),m?y:w}{let r=this.tone(t);if(null==this.background)return r;const n=this.background(t).getTone(t),a=this.contrastCurve.getContrast(t.contrastLevel);if(x.ratioOfTones(n,r)>=a||(r=D.foregroundTone(n,a)),e&&(r=D.foregroundTone(n,a)),this.isBackground&&50<=r&&r<60&&(r=x.ratioOfTones(49,n)>=a?49:60),this.secondBackground){const[e,n]=[this.background,this.secondBackground],[o,i]=[e(t).getTone(t),n(t).getTone(t)],[s,c]=[Math.max(o,i),Math.min(o,i)];if(x.ratioOfTones(s,r)>=a&&x.ratioOfTones(c,r)>=a)return r;const l=x.lighter(s,a),u=x.darker(c,a),h=[];-1!==l&&h.push(l),-1!==u&&h.push(u);return D.tonePrefersLightForeground(o)||D.tonePrefersLightForeground(i)?l<0?100:l:1===h.length?h[0]:u<0?0:u}return r}}static foregroundTone(t,e){const r=x.lighterUnsafe(t,e),n=x.darkerUnsafe(t,e),a=x.ratioOfTones(r,t),o=x.ratioOfTones(n,t);if(D.tonePrefersLightForeground(t)){const t=Math.abs(a-o)<.1&&a=e||a>=o||t?r:n}return o>=e||o>=a?n:r}static tonePrefersLightForeground(t){return Math.round(t)<60}static toneAllowsLightForeground(t){return Math.round(t)<=49}static enableLightForeground(t){return D.tonePrefersLightForeground(t)&&!D.toneAllowsLightForeground(t)?49:t}} +/** + * @license + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */var A;!function(t){t[t.MONOCHROME=0]="MONOCHROME",t[t.NEUTRAL=1]="NEUTRAL",t[t.TONAL_SPOT=2]="TONAL_SPOT",t[t.VIBRANT=3]="VIBRANT",t[t.EXPRESSIVE=4]="EXPRESSIVE",t[t.FIDELITY=5]="FIDELITY",t[t.CONTENT=6]="CONTENT",t[t.RAINBOW=7]="RAINBOW",t[t.FRUIT_SALAD=8]="FRUIT_SALAD"}(A||(A={})); +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class _{constructor(t,e,r,n){this.low=t,this.normal=e,this.medium=r,this.high=n}getContrast(t){return t<=-1?this.low:t<0?e(this.low,this.normal,(t- -1)/1):t<.5?e(this.normal,this.medium,(t-0)/.5):t<1?e(this.medium,this.high,(t-.5)/.5):this.high}} +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */class O{constructor(t,e,r,n,a){this.roleA=t,this.roleB=e,this.delta=r,this.polarity=n,this.stayTogether=a}} +/** + * @license + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */function S(t){return t.variant===A.FIDELITY||t.variant===A.CONTENT}function T(t){return t.variant===A.MONOCHROME}function B(t,e){const r=t.inViewingConditions(function(t){return w.make(void 0,void 0,t.isDark?30:80,void 0,void 0)}(e));return D.tonePrefersLightForeground(t.tone)&&!D.toneAllowsLightForeground(r.tone)?D.enableLightForeground(t.tone):D.enableLightForeground(r.tone)}class H{static highestSurface(t){return t.isDark?H.surfaceBright:H.surfaceDim}}H.contentAccentToneDelta=15,H.primaryPaletteKeyColor=D.fromPalette({name:"primary_palette_key_color",palette:t=>t.primaryPalette,tone:t=>t.primaryPalette.keyColor.tone}),H.secondaryPaletteKeyColor=D.fromPalette({name:"secondary_palette_key_color",palette:t=>t.secondaryPalette,tone:t=>t.secondaryPalette.keyColor.tone}),H.tertiaryPaletteKeyColor=D.fromPalette({name:"tertiary_palette_key_color",palette:t=>t.tertiaryPalette,tone:t=>t.tertiaryPalette.keyColor.tone}),H.neutralPaletteKeyColor=D.fromPalette({name:"neutral_palette_key_color",palette:t=>t.neutralPalette,tone:t=>t.neutralPalette.keyColor.tone}),H.neutralVariantPaletteKeyColor=D.fromPalette({name:"neutral_variant_palette_key_color",palette:t=>t.neutralVariantPalette,tone:t=>t.neutralVariantPalette.keyColor.tone}),H.background=D.fromPalette({name:"background",palette:t=>t.neutralPalette,tone:t=>t.isDark?6:98,isBackground:!0}),H.onBackground=D.fromPalette({name:"on_background",palette:t=>t.neutralPalette,tone:t=>t.isDark?90:10,background:t=>H.background,contrastCurve:new _(3,3,4.5,7)}),H.surface=D.fromPalette({name:"surface",palette:t=>t.neutralPalette,tone:t=>t.isDark?6:98,isBackground:!0}),H.surfaceDim=D.fromPalette({name:"surface_dim",palette:t=>t.neutralPalette,tone:t=>t.isDark?6:87,isBackground:!0}),H.surfaceBright=D.fromPalette({name:"surface_bright",palette:t=>t.neutralPalette,tone:t=>t.isDark?24:98,isBackground:!0}),H.surfaceContainerLowest=D.fromPalette({name:"surface_container_lowest",palette:t=>t.neutralPalette,tone:t=>t.isDark?4:100,isBackground:!0}),H.surfaceContainerLow=D.fromPalette({name:"surface_container_low",palette:t=>t.neutralPalette,tone:t=>t.isDark?10:96,isBackground:!0}),H.surfaceContainer=D.fromPalette({name:"surface_container",palette:t=>t.neutralPalette,tone:t=>t.isDark?12:94,isBackground:!0}),H.surfaceContainerHigh=D.fromPalette({name:"surface_container_high",palette:t=>t.neutralPalette,tone:t=>t.isDark?17:92,isBackground:!0}),H.surfaceContainerHighest=D.fromPalette({name:"surface_container_highest",palette:t=>t.neutralPalette,tone:t=>t.isDark?22:90,isBackground:!0}),H.onSurface=D.fromPalette({name:"on_surface",palette:t=>t.neutralPalette,tone:t=>t.isDark?90:10,background:t=>H.highestSurface(t),contrastCurve:new _(4.5,7,11,21)}),H.surfaceVariant=D.fromPalette({name:"surface_variant",palette:t=>t.neutralVariantPalette,tone:t=>t.isDark?30:90,isBackground:!0}),H.onSurfaceVariant=D.fromPalette({name:"on_surface_variant",palette:t=>t.neutralVariantPalette,tone:t=>t.isDark?80:30,background:t=>H.highestSurface(t),contrastCurve:new _(3,4.5,7,11)}),H.inverseSurface=D.fromPalette({name:"inverse_surface",palette:t=>t.neutralPalette,tone:t=>t.isDark?90:20}),H.inverseOnSurface=D.fromPalette({name:"inverse_on_surface",palette:t=>t.neutralPalette,tone:t=>t.isDark?20:95,background:t=>H.inverseSurface,contrastCurve:new _(4.5,7,11,21)}),H.outline=D.fromPalette({name:"outline",palette:t=>t.neutralVariantPalette,tone:t=>t.isDark?60:50,background:t=>H.highestSurface(t),contrastCurve:new _(1.5,3,4.5,7)}),H.outlineVariant=D.fromPalette({name:"outline_variant",palette:t=>t.neutralVariantPalette,tone:t=>t.isDark?30:80,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7)}),H.shadow=D.fromPalette({name:"shadow",palette:t=>t.neutralPalette,tone:t=>0}),H.scrim=D.fromPalette({name:"scrim",palette:t=>t.neutralPalette,tone:t=>0}),H.surfaceTint=D.fromPalette({name:"surface_tint",palette:t=>t.primaryPalette,tone:t=>t.isDark?80:40,isBackground:!0}),H.primary=D.fromPalette({name:"primary",palette:t=>t.primaryPalette,tone:t=>T(t)?t.isDark?100:0:t.isDark?80:40,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(3,4.5,7,11),toneDeltaPair:t=>new O(H.primaryContainer,H.primary,15,"nearer",!1)}),H.onPrimary=D.fromPalette({name:"on_primary",palette:t=>t.primaryPalette,tone:t=>T(t)?t.isDark?10:90:t.isDark?20:100,background:t=>H.primary,contrastCurve:new _(4.5,7,11,21)}),H.primaryContainer=D.fromPalette({name:"primary_container",palette:t=>t.primaryPalette,tone:t=>S(t)?B(t.sourceColorHct,t):T(t)?t.isDark?85:25:t.isDark?30:90,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.primaryContainer,H.primary,15,"nearer",!1)}),H.onPrimaryContainer=D.fromPalette({name:"on_primary_container",palette:t=>t.primaryPalette,tone:t=>S(t)?D.foregroundTone(H.primaryContainer.tone(t),4.5):T(t)?t.isDark?0:100:t.isDark?90:10,background:t=>H.primaryContainer,contrastCurve:new _(4.5,7,11,21)}),H.inversePrimary=D.fromPalette({name:"inverse_primary",palette:t=>t.primaryPalette,tone:t=>t.isDark?40:80,background:t=>H.inverseSurface,contrastCurve:new _(3,4.5,7,11)}),H.secondary=D.fromPalette({name:"secondary",palette:t=>t.secondaryPalette,tone:t=>t.isDark?80:40,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(3,4.5,7,11),toneDeltaPair:t=>new O(H.secondaryContainer,H.secondary,15,"nearer",!1)}),H.onSecondary=D.fromPalette({name:"on_secondary",palette:t=>t.secondaryPalette,tone:t=>T(t)?t.isDark?10:100:t.isDark?20:100,background:t=>H.secondary,contrastCurve:new _(4.5,7,11,21)}),H.secondaryContainer=D.fromPalette({name:"secondary_container",palette:t=>t.secondaryPalette,tone:t=>{const e=t.isDark?30:90;if(T(t))return t.isDark?30:85;if(!S(t))return e;let r=function(t,e,r,n){let a=r,o=C.from(t,e,r);if(o.chromai.chroma)break;if(Math.abs(i.chroma-e)<.4)break;Math.abs(i.chroma-e)H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.secondaryContainer,H.secondary,15,"nearer",!1)}),H.onSecondaryContainer=D.fromPalette({name:"on_secondary_container",palette:t=>t.secondaryPalette,tone:t=>S(t)?D.foregroundTone(H.secondaryContainer.tone(t),4.5):t.isDark?90:10,background:t=>H.secondaryContainer,contrastCurve:new _(4.5,7,11,21)}),H.tertiary=D.fromPalette({name:"tertiary",palette:t=>t.tertiaryPalette,tone:t=>T(t)?t.isDark?90:25:t.isDark?80:40,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(3,4.5,7,11),toneDeltaPair:t=>new O(H.tertiaryContainer,H.tertiary,15,"nearer",!1)}),H.onTertiary=D.fromPalette({name:"on_tertiary",palette:t=>t.tertiaryPalette,tone:t=>T(t)?t.isDark?10:90:t.isDark?20:100,background:t=>H.tertiary,contrastCurve:new _(4.5,7,11,21)}),H.tertiaryContainer=D.fromPalette({name:"tertiary_container",palette:t=>t.tertiaryPalette,tone:t=>{if(T(t))return t.isDark?60:49;if(!S(t))return t.isDark?30:90;const e=B(t.tertiaryPalette.getHct(t.sourceColorHct.tone),t),r=t.tertiaryPalette.getHct(e);return I.fixIfDisliked(r).tone},isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.tertiaryContainer,H.tertiary,15,"nearer",!1)}),H.onTertiaryContainer=D.fromPalette({name:"on_tertiary_container",palette:t=>t.tertiaryPalette,tone:t=>T(t)?t.isDark?0:100:S(t)?D.foregroundTone(H.tertiaryContainer.tone(t),4.5):t.isDark?90:10,background:t=>H.tertiaryContainer,contrastCurve:new _(4.5,7,11,21)}),H.error=D.fromPalette({name:"error",palette:t=>t.errorPalette,tone:t=>t.isDark?80:40,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(3,4.5,7,11),toneDeltaPair:t=>new O(H.errorContainer,H.error,15,"nearer",!1)}),H.onError=D.fromPalette({name:"on_error",palette:t=>t.errorPalette,tone:t=>t.isDark?20:100,background:t=>H.error,contrastCurve:new _(4.5,7,11,21)}),H.errorContainer=D.fromPalette({name:"error_container",palette:t=>t.errorPalette,tone:t=>t.isDark?30:90,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.errorContainer,H.error,15,"nearer",!1)}),H.onErrorContainer=D.fromPalette({name:"on_error_container",palette:t=>t.errorPalette,tone:t=>t.isDark?90:10,background:t=>H.errorContainer,contrastCurve:new _(4.5,7,11,21)}),H.primaryFixed=D.fromPalette({name:"primary_fixed",palette:t=>t.primaryPalette,tone:t=>T(t)?40:90,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.primaryFixed,H.primaryFixedDim,10,"lighter",!0)}),H.primaryFixedDim=D.fromPalette({name:"primary_fixed_dim",palette:t=>t.primaryPalette,tone:t=>T(t)?30:80,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.primaryFixed,H.primaryFixedDim,10,"lighter",!0)}),H.onPrimaryFixed=D.fromPalette({name:"on_primary_fixed",palette:t=>t.primaryPalette,tone:t=>T(t)?100:10,background:t=>H.primaryFixedDim,secondBackground:t=>H.primaryFixed,contrastCurve:new _(4.5,7,11,21)}),H.onPrimaryFixedVariant=D.fromPalette({name:"on_primary_fixed_variant",palette:t=>t.primaryPalette,tone:t=>T(t)?90:30,background:t=>H.primaryFixedDim,secondBackground:t=>H.primaryFixed,contrastCurve:new _(3,4.5,7,11)}),H.secondaryFixed=D.fromPalette({name:"secondary_fixed",palette:t=>t.secondaryPalette,tone:t=>T(t)?80:90,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.secondaryFixed,H.secondaryFixedDim,10,"lighter",!0)}),H.secondaryFixedDim=D.fromPalette({name:"secondary_fixed_dim",palette:t=>t.secondaryPalette,tone:t=>T(t)?70:80,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.secondaryFixed,H.secondaryFixedDim,10,"lighter",!0)}),H.onSecondaryFixed=D.fromPalette({name:"on_secondary_fixed",palette:t=>t.secondaryPalette,tone:t=>10,background:t=>H.secondaryFixedDim,secondBackground:t=>H.secondaryFixed,contrastCurve:new _(4.5,7,11,21)}),H.onSecondaryFixedVariant=D.fromPalette({name:"on_secondary_fixed_variant",palette:t=>t.secondaryPalette,tone:t=>T(t)?25:30,background:t=>H.secondaryFixedDim,secondBackground:t=>H.secondaryFixed,contrastCurve:new _(3,4.5,7,11)}),H.tertiaryFixed=D.fromPalette({name:"tertiary_fixed",palette:t=>t.tertiaryPalette,tone:t=>T(t)?40:90,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.tertiaryFixed,H.tertiaryFixedDim,10,"lighter",!0)}),H.tertiaryFixedDim=D.fromPalette({name:"tertiary_fixed_dim",palette:t=>t.tertiaryPalette,tone:t=>T(t)?30:80,isBackground:!0,background:t=>H.highestSurface(t),contrastCurve:new _(1,1,3,7),toneDeltaPair:t=>new O(H.tertiaryFixed,H.tertiaryFixedDim,10,"lighter",!0)}),H.onTertiaryFixed=D.fromPalette({name:"on_tertiary_fixed",palette:t=>t.tertiaryPalette,tone:t=>T(t)?100:10,background:t=>H.tertiaryFixedDim,secondBackground:t=>H.tertiaryFixed,contrastCurve:new _(4.5,7,11,21)}),H.onTertiaryFixedVariant=D.fromPalette({name:"on_tertiary_fixed_variant",palette:t=>t.tertiaryPalette,tone:t=>T(t)?90:30,background:t=>H.tertiaryFixedDim,secondBackground:t=>H.tertiaryFixed,contrastCurve:new _(3,4.5,7,11)}); +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class ${static fromInt(t){const e=C.fromInt(t);return $.fromHct(e)}static fromHct(t){return new $(t.hue,t.chroma,t)}static fromHueAndChroma(t,e){return new $(t,e,$.createKeyColor(t,e))}constructor(t,e,r){this.hue=t,this.chroma=e,this.keyColor=r,this.cache=new Map}static createKeyColor(t,e){let r=C.from(t,e,50),n=Math.abs(r.chroma-e);for(let a=1;a<50;a+=1){if(Math.round(e)===Math.round(r.chroma))return r;const o=C.from(t,e,50+a),i=Math.abs(o.chroma-e);i0)return this.hctsByTempCache;const t=this.hctsByHue.concat([this.input]),e=this.tempsByHct;return t.sort(((t,r)=>e.get(t)-e.get(r))),this.hctsByTempCache=t,t}get warmest(){return this.hctsByTemp[this.hctsByTemp.length-1]}get coldest(){return this.hctsByTemp[0]}analogous(t=5,e=12){const r=Math.round(this.input.hue),a=this.hctsByHue[r];let o=this.relativeTemperature(a);const i=[a];let s=0;for(let t=0;t<360;t++){const e=n(r+t),a=this.hctsByHue[e],i=this.relativeTemperature(a),c=Math.abs(i-o);o=i,s+=c}let c=1;const l=s/e;let u=0;for(o=this.relativeTemperature(a);i.length=i.length*l,d=1;for(;h&&i.length=(i.length+d)*l,d++}if(o=s,c++,c>360){for(;i.length=i.length&&(e%=i.length),h.splice(0,0,i[e])}const m=t-d-1;for(let t=1;t=i.length&&(e%=i.length),h.push(i[e])}return h}get complement(){if(null!=this.complementCache)return this.complementCache;const t=this.coldest.hue,e=this.tempsByHct.get(this.coldest),r=this.warmest.hue,n=this.tempsByHct.get(this.warmest)-e,o=L.isBetween(this.input.hue,t,r),i=o?r:t,s=o?t:r;let c=1e3,l=this.hctsByHue[Math.round(this.input.hue)];const u=1-this.inputRelativeTemperature;for(let t=0;t<=360;t+=1){const r=a(i+1*t);if(!L.isBetween(r,i,s))continue;const o=this.hctsByHue[Math.round(r)],h=(this.tempsByHct.get(o)-e)/n,d=Math.abs(u-h);d=0||(this.inputRelativeTemperatureCache=this.relativeTemperature(this.input)),this.inputRelativeTemperatureCache}get tempsByHct(){if(this.tempsByHctCache.size>0)return this.tempsByHctCache;const t=this.hctsByHue.concat([this.input]),e=new Map;for(const r of t)e.set(r,L.rawTemperature(r));return this.tempsByHctCache=e,e}get hctsByHue(){if(this.hctsByHueCache.length>0)return this.hctsByHueCache;const t=[];for(let e=0;e<=360;e+=1){const r=C.from(e,this.input.chroma,this.input.tone);t.push(r)}return this.hctsByHueCache=t,this.hctsByHueCache}static isBetween(t,e,r){return e>>0}function J(t){return parseInt(t,16)} +/** + * @license + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */U.hues=[0,41,61,101,131,181,251,301,360],U.secondaryRotations=[18,15,10,12,15,18,15,12,12],U.tertiaryRotations=[35,30,20,25,30,35,30,25,25];const K={background:H.background,"on-background":H.onBackground,surface:H.surface,"surface-dim":H.surfaceDim,"surface-bright":H.surfaceBright,"surface-container-lowest":H.surfaceContainerLowest,"surface-container-low":H.surfaceContainerLow,"surface-container":H.surfaceContainer,"surface-container-high":H.surfaceContainerHigh,"surface-container-highest":H.surfaceContainerHighest,"on-surface":H.onSurface,"on-surface-dim":H.onSurface,"on-surface-bright":H.onSurface,"on-surface-container-lowest":H.onSurface,"on-surface-container-low":H.onSurface,"on-surface-container":H.onSurface,"on-surface-container-high":H.onSurface,"on-surface-container-highest":H.onSurface,"surface-variant":H.surfaceVariant,"on-surface-variant":H.onSurfaceVariant,"inverse-surface":H.inverseSurface,"on-inverse-surface":H.inverseOnSurface,outline:H.outline,"outline-variant":H.outlineVariant,"surface-tint":H.surfaceTint,"on-surface-tint":H.onSurface,primary:H.primary,"on-primary":H.onPrimary,"primary-container":H.primaryContainer,"on-primary-container":H.onPrimaryContainer,"inverse-primary":H.inversePrimary,secondary:H.secondary,"on-secondary":H.onSecondary,"secondary-container":H.secondaryContainer,"on-secondary-container":H.onSecondaryContainer,tertiary:H.tertiary,"on-tertiary":H.onTertiary,"tertiary-container":H.tertiaryContainer,"on-tertiary-container":H.onTertiaryContainer,error:H.error,"on-error":H.onError,"error-container":H.errorContainer,"on-error-container":H.onErrorContainer},X=(t,e,r)=>{const{primary:n,...a}=t,o=G(n),i={content:R,expressive:E,fidelity:V,monochrome:N,neutral:q,tonalSpot:z,vibrant:U},s=i[e]||i.content,c=new s(C.fromInt(o),!1,r),l=new s(C.fromInt(o),!0,r),u={transparent:"transparent",current:"currentColor",black:"#000000",white:"#ffffff"};return Object.entries(K).forEach((([t,e])=>{const r=Y(e.getArgb(c)),n=Y(e.getArgb(l));u[`${t}-light`]=r,u[`${t}-dark`]=n})),Object.keys(a).forEach((t=>{const e=a[t],r="string"==typeof e?e:e.hex,n=e===r||e.harmonize,{light:i,dark:s}=function(t,e){let r=e.value;const n=r,a=t;e.blend&&(r=P.harmonize(n,a));const o=F.of(r).a1;return{color:e,value:r,light:{color:o.tone(40),onColor:o.tone(100),colorContainer:o.tone(90),onColorContainer:o.tone(10)},dark:{color:o.tone(80),onColor:o.tone(20),colorContainer:o.tone(30),onColorContainer:o.tone(90)}}}(o,{value:G(r),blend:n}),c=t.split("").map(((t,e)=>t.toUpperCase()===t?`${0!==e?"-":""}${t.toLowerCase()}`:t)).join("");u[`${c}-light`]=Y(i.color),u[`on-${c}-light`]=Y(i.onColor),u[`${c}-container-light`]=Y(i.colorContainer),u[`on-${c}-container-light`]=Y(i.onColorContainer),u[`${c}-dark`]=Y(s.color),u[`on-${c}-dark`]=Y(s.onColor),u[`${c}-container-dark`]=Y(s.colorContainer),u[`on-${c}-container-dark`]=Y(s.onColorContainer)})),u};var W={},Q={};!function(t){function e(t,e){return{handler:t,config:e}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return r}}),e.withOptions=function(t,e=(()=>({}))){const r=function(r){return{__options:r,handler:t(r),config:e(r)}};return r.__isOptionsFunction=!0,r.__pluginFunction=t,r.__configFunction=e,r};const r=e}(Q),function(t){Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return r}});function e(t){return t&&t.__esModule?t:{default:t}}const r=e(Q).default}(W);var Z=(W.__esModule?W:{default:W}).default,tt={};!function(t){function e(t){return"function"==typeof t?t({}):t}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return e}})}(tt);var et={};!function(t){Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return r}});const e=t=>Object.assign({},...Object.entries(null!=t?t:{}).flatMap((([t,r])=>"object"==typeof r?Object.entries(e(r)).map((([e,r])=>({[t+("DEFAULT"===e?"":`-${e}`)]:r}))):[{[`${t}`]:r}]))),r=e}(et);var rt={},nt={},at={};!function(t){Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return e}});const e={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}}(at),function(t){Object.defineProperty(t,"__esModule",{value:!0}),function(t,e){for(var r in e)Object.defineProperty(t,r,{enumerable:!0,get:e[r]})}(t,{parseColor:function(){return h},formatColor:function(){return d}});const e=r(at);function r(t){return t&&t.__esModule?t:{default:t}}let n=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,a=/^#([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i,o=/(?:\d+|\d*\.\d+)%?/,i=/(?:\s*,\s*|\s+)/,s=/\s*[,/]\s*/,c=/var\(--(?:[^ )]*?)(?:,(?:[^ )]*?|var\(--[^ )]*?\)))?\)/,l=new RegExp(`^(rgba?)\\(\\s*(${o.source}|${c.source})(?:${i.source}(${o.source}|${c.source}))?(?:${i.source}(${o.source}|${c.source}))?(?:${s.source}(${o.source}|${c.source}))?\\s*\\)$`),u=new RegExp(`^(hsla?)\\(\\s*((?:${o.source})(?:deg|rad|grad|turn)?|${c.source})(?:${i.source}(${o.source}|${c.source}))?(?:${i.source}(${o.source}|${c.source}))?(?:${s.source}(${o.source}|${c.source}))?\\s*\\)$`);function h(t,{loose:r=!1}={}){var o,i;if("string"!=typeof t)return null;if("transparent"===(t=t.trim()))return{mode:"rgb",color:["0","0","0"],alpha:"0"};if(t in e.default)return{mode:"rgb",color:e.default[t].map((t=>t.toString()))};let s=t.replace(a,((t,e,r,n,a)=>["#",e,e,r,r,n,n,a?a+a:""].join(""))).match(n);if(null!==s)return{mode:"rgb",color:[parseInt(s[1],16),parseInt(s[2],16),parseInt(s[3],16)].map((t=>t.toString())),alpha:s[4]?(parseInt(s[4],16)/255).toString():void 0};var c;let h=null!==(c=t.match(l))&&void 0!==c?c:t.match(u);if(null===h)return null;let d=[h[2],h[3],h[4]].filter(Boolean).map((t=>t.toString()));return 2===d.length&&d[0].startsWith("var(")?{mode:h[1],color:[d[0]],alpha:d[1]}:r||3===d.length?d.length<3&&!d.some((t=>/^var\(.*?\)$/.test(t)))?null:{mode:h[1],color:d,alpha:null===(o=h[5])||void 0===o||null===(i=o.toString)||void 0===i?void 0:i.call(o)}:null}function d({mode:t,color:e,alpha:r}){let n=void 0!==r;return"rgba"===t||"hsla"===t?`${t}(${e.join(", ")}${n?`, ${r}`:""})`:`${t}(${e.join(" ")}${n?` / ${r}`:""})`}}(nt),function(t){Object.defineProperty(t,"__esModule",{value:!0}),function(t,e){for(var r in e)Object.defineProperty(t,r,{enumerable:!0,get:e[r]})}(t,{withAlphaValue:function(){return r},default:function(){return n}});const e=nt;function r(t,r,n){if("function"==typeof t)return t({opacityValue:r});let a=(0,e.parseColor)(t,{loose:!0});return null===a?n:(0,e.formatColor)({...a,alpha:r})}function n({color:t,property:r,variable:n}){let a=[].concat(r);if("function"==typeof t)return{[n]:"1",...Object.fromEntries(a.map((e=>[e,t({opacityVariable:n,opacityValue:`var(${n})`})])))};const o=(0,e.parseColor)(t);return null===o||void 0!==o.alpha?Object.fromEntries(a.map((e=>[e,t]))):{[n]:"1",...Object.fromEntries(a.map((t=>[t,(0,e.formatColor)({...o,alpha:`var(${n})`})])))}}}(rt);const ot=Z,{default:it}=tt,{default:st}=et,{default:ct}=rt,lt={bgMix:"bg-mix",bgMixAmount:"bg-mix-amount",bgMixMethod:"bg-mix-method"};const ut=(t={})=>ot((({matchUtilities:e,theme:r,corePlugins:n})=>{const{bgMix:a,bgMixAmount:o,bgMixMethod:i}={...lt,...t};e({[a]:t=>{const{mixColor:e,...r}=ct({color:t,property:"mixColor",variable:"--tw-bg-mix-opacity"});return{...r,"background-color":`color-mix(var(--tw-bg-mix-method, in srgb), ${e} calc(var(--tw-bg-mix-amount, 0) * 1%), var(--tw-bg-base))`}}},{values:st(r("backgroundColor")),type:["color","any"]}),e({[o]:t=>({"--tw-bg-mix-amount":t})},{values:Object.fromEntries(Object.entries(r("backgroundOpacity")).map((([t,e])=>[t,""+100*e])))}),e({[i]:t=>({"--tw-bg-mix-method":t})},{values:{srgb:"in srgb","shorter-hue":"in hsl shorter hue","longer-hue":"in hsl longer hue"}}),e({bg:t=>n("backgroundOpacity")?ct({color:t,property:"--tw-bg-base",variable:"--tw-bg-opacity"}):{"background-color":it(t)}},{values:st(r("backgroundColor")),type:["color","any"]})})),ht=Z,{default:dt}=et,mt={hoverAmount:"8",pressAmount:"12",focusAmount:"12",dragAmount:"16",surfacePrefix:"surface",interactiveSurfacePrefix:"interactive-surface",draggedSurfacePrefix:"dragged-surface",disabledStyles:{textOpacity:.38,backgroundOpacity:.12,colorName:"black"},transition:{duration:150}};var ft=(t={})=>{const{surfacePrefix:e,interactiveSurfacePrefix:r,draggedSurfacePrefix:n,disabledStyles:a,transition:o,...i}={...mt,...t};return[ut(),ht((({matchComponents:t,theme:s})=>{const c=dt(s("colors")),l=Object.keys(c).filter((t=>c[`on-${t}`])),u=Object.fromEntries(l.map((t=>[t,t])));t({[e]:t=>({..."bg"===e?{}:{[`@apply bg-${t}`]:{}},[`@apply text-on-${t}`]:{}}),[r]:t=>({[`@apply bg-${t}`]:{},[`@apply text-on-${t}`]:{},[`@apply bg-mix-on-${t}`]:{},...o?{"@apply transition-colors":{},[`@apply duration-${o.duration}`]:{}}:{},[`@apply hover:bg-mix-amount-[${i.hoverAmount}]`]:{},[`@apply active:bg-mix-amount-[${i.pressAmount}]`]:{},[`@apply focus-visible:bg-mix-amount-[${i.focusAmount}]`]:{},...a?{[`@apply disabled:text-${a.colorName}/[${a.textOpacity}]`]:{},[`@apply disabled:bg-${a.colorName}/[${a.backgroundOpacity}]`]:{}}:{}}),[n]:t=>({[`@apply bg-${t}`]:{},[`@apply text-on-${t}`]:{},[`@apply bg-mix-on-${t}`]:{},[`@apply bg-mix-amount-[${i.dragAmount}]`]:{},...o?{"@apply transition-colors":{},[`@apply duration-${o.duration}`]:{}}:{}})},{values:u})}),{})]},gt={exports:{}},pt={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},bt={exports:{}},yt=function(t){return!(!t||"string"==typeof t)&&(t instanceof Array||Array.isArray(t)||t.length>=0&&(t.splice instanceof Function||Object.getOwnPropertyDescriptor(t,t.length-1)&&"String"!==t.constructor.name))},kt=Array.prototype.concat,wt=Array.prototype.slice,vt=bt.exports=function(t){for(var e=[],r=0,n=t.length;r=4&&1!==t[3]&&(e=", "+t[3]),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+e+")"},Dt.to.keyword=function(t){return xt[t.slice(0,3)]};const Ot=pt,St={};for(const t of Object.keys(Ot))St[Ot[t]]=t;const Tt={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};var Bt=Tt;for(const t of Object.keys(Tt)){if(!("channels"in Tt[t]))throw new Error("missing channels property: "+t);if(!("labels"in Tt[t]))throw new Error("missing channel labels property: "+t);if(Tt[t].labels.length!==Tt[t].channels)throw new Error("channel and label counts mismatch: "+t);const{channels:e,labels:r}=Tt[t];delete Tt[t].channels,delete Tt[t].labels,Object.defineProperty(Tt[t],"channels",{value:e}),Object.defineProperty(Tt[t],"labels",{value:r})}Tt.rgb.hsl=function(t){const e=t[0]/255,r=t[1]/255,n=t[2]/255,a=Math.min(e,r,n),o=Math.max(e,r,n),i=o-a;let s,c;o===a?s=0:e===o?s=(r-n)/i:r===o?s=2+(n-e)/i:n===o&&(s=4+(e-r)/i),s=Math.min(60*s,360),s<0&&(s+=360);const l=(a+o)/2;return c=o===a?0:l<=.5?i/(o+a):i/(2-o-a),[s,100*c,100*l]},Tt.rgb.hsv=function(t){let e,r,n,a,o;const i=t[0]/255,s=t[1]/255,c=t[2]/255,l=Math.max(i,s,c),u=l-Math.min(i,s,c),h=function(t){return(l-t)/6/u+.5};return 0===u?(a=0,o=0):(o=u/l,e=h(i),r=h(s),n=h(c),i===l?a=n-r:s===l?a=1/3+e-n:c===l&&(a=2/3+r-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*o,100*l]},Tt.rgb.hwb=function(t){const e=t[0],r=t[1];let n=t[2];const a=Tt.rgb.hsl(t)[0],o=1/255*Math.min(e,Math.min(r,n));return n=1-1/255*Math.max(e,Math.max(r,n)),[a,100*o,100*n]},Tt.rgb.cmyk=function(t){const e=t[0]/255,r=t[1]/255,n=t[2]/255,a=Math.min(1-e,1-r,1-n);return[100*((1-e-a)/(1-a)||0),100*((1-r-a)/(1-a)||0),100*((1-n-a)/(1-a)||0),100*a]},Tt.rgb.keyword=function(t){const e=St[t];if(e)return e;let r,n=1/0;for(const e of Object.keys(Ot)){const i=(o=Ot[e],((a=t)[0]-o[0])**2+(a[1]-o[1])**2+(a[2]-o[2])**2);i.04045?((e+.055)/1.055)**2.4:e/12.92,r=r>.04045?((r+.055)/1.055)**2.4:r/12.92,n=n>.04045?((n+.055)/1.055)**2.4:n/12.92;return[100*(.4124*e+.3576*r+.1805*n),100*(.2126*e+.7152*r+.0722*n),100*(.0193*e+.1192*r+.9505*n)]},Tt.rgb.lab=function(t){const e=Tt.rgb.xyz(t);let r=e[0],n=e[1],a=e[2];r/=95.047,n/=100,a/=108.883,r=r>.008856?r**(1/3):7.787*r+16/116,n=n>.008856?n**(1/3):7.787*n+16/116,a=a>.008856?a**(1/3):7.787*a+16/116;return[116*n-16,500*(r-n),200*(n-a)]},Tt.hsl.rgb=function(t){const e=t[0]/360,r=t[1]/100,n=t[2]/100;let a,o,i;if(0===r)return i=255*n,[i,i,i];a=n<.5?n*(1+r):n+r-n*r;const s=2*n-a,c=[0,0,0];for(let t=0;t<3;t++)o=e+1/3*-(t-1),o<0&&o++,o>1&&o--,i=6*o<1?s+6*(a-s)*o:2*o<1?a:3*o<2?s+(a-s)*(2/3-o)*6:s,c[t]=255*i;return c},Tt.hsl.hsv=function(t){const e=t[0];let r=t[1]/100,n=t[2]/100,a=r;const o=Math.max(n,.01);n*=2,r*=n<=1?n:2-n,a*=o<=1?o:2-o;return[e,100*(0===n?2*a/(o+a):2*r/(n+r)),100*((n+r)/2)]},Tt.hsv.rgb=function(t){const e=t[0]/60,r=t[1]/100;let n=t[2]/100;const a=Math.floor(e)%6,o=e-Math.floor(e),i=255*n*(1-r),s=255*n*(1-r*o),c=255*n*(1-r*(1-o));switch(n*=255,a){case 0:return[n,c,i];case 1:return[s,n,i];case 2:return[i,n,c];case 3:return[i,s,n];case 4:return[c,i,n];case 5:return[n,i,s]}},Tt.hsv.hsl=function(t){const e=t[0],r=t[1]/100,n=t[2]/100,a=Math.max(n,.01);let o,i;i=(2-r)*n;const s=(2-r)*a;return o=r*a,o/=s<=1?s:2-s,o=o||0,i/=2,[e,100*o,100*i]},Tt.hwb.rgb=function(t){const e=t[0]/360;let r=t[1]/100,n=t[2]/100;const a=r+n;let o;a>1&&(r/=a,n/=a);const i=Math.floor(6*e),s=1-n;o=6*e-i,0!=(1&i)&&(o=1-o);const c=r+o*(s-r);let l,u,h;switch(i){default:case 6:case 0:l=s,u=c,h=r;break;case 1:l=c,u=s,h=r;break;case 2:l=r,u=s,h=c;break;case 3:l=r,u=c,h=s;break;case 4:l=c,u=r,h=s;break;case 5:l=s,u=r,h=c}return[255*l,255*u,255*h]},Tt.cmyk.rgb=function(t){const e=t[0]/100,r=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,r*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]},Tt.xyz.rgb=function(t){const e=t[0]/100,r=t[1]/100,n=t[2]/100;let a,o,i;return a=3.2406*e+-1.5372*r+-.4986*n,o=-.9689*e+1.8758*r+.0415*n,i=.0557*e+-.204*r+1.057*n,a=a>.0031308?1.055*a**(1/2.4)-.055:12.92*a,o=o>.0031308?1.055*o**(1/2.4)-.055:12.92*o,i=i>.0031308?1.055*i**(1/2.4)-.055:12.92*i,a=Math.min(Math.max(0,a),1),o=Math.min(Math.max(0,o),1),i=Math.min(Math.max(0,i),1),[255*a,255*o,255*i]},Tt.xyz.lab=function(t){let e=t[0],r=t[1],n=t[2];e/=95.047,r/=100,n/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,r=r>.008856?r**(1/3):7.787*r+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;return[116*r-16,500*(e-r),200*(r-n)]},Tt.lab.xyz=function(t){let e,r,n;r=(t[0]+16)/116,e=t[1]/500+r,n=r-t[2]/200;const a=r**3,o=e**3,i=n**3;return r=a>.008856?a:(r-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,n=i>.008856?i:(n-16/116)/7.787,e*=95.047,r*=100,n*=108.883,[e,r,n]},Tt.lab.lch=function(t){const e=t[0],r=t[1],n=t[2];let a;a=360*Math.atan2(n,r)/2/Math.PI,a<0&&(a+=360);return[e,Math.sqrt(r*r+n*n),a]},Tt.lch.lab=function(t){const e=t[0],r=t[1],n=t[2]/360*2*Math.PI;return[e,r*Math.cos(n),r*Math.sin(n)]},Tt.rgb.ansi16=function(t,e=null){const[r,n,a]=t;let o=null===e?Tt.rgb.hsv(t)[2]:e;if(o=Math.round(o/50),0===o)return 30;let i=30+(Math.round(a/255)<<2|Math.round(n/255)<<1|Math.round(r/255));return 2===o&&(i+=60),i},Tt.hsv.ansi16=function(t){return Tt.rgb.ansi16(Tt.hsv.rgb(t),t[2])},Tt.rgb.ansi256=function(t){const e=t[0],r=t[1],n=t[2];if(e===r&&r===n)return e<8?16:e>248?231:Math.round((e-8)/247*24)+232;return 16+36*Math.round(e/255*5)+6*Math.round(r/255*5)+Math.round(n/255*5)},Tt.ansi16.rgb=function(t){let e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),e=e/10.5*255,[e,e,e];const r=.5*(1+~~(t>50));return[(1&e)*r*255,(e>>1&1)*r*255,(e>>2&1)*r*255]},Tt.ansi256.rgb=function(t){if(t>=232){const e=10*(t-232)+8;return[e,e,e]}let e;t-=16;return[Math.floor(t/36)/5*255,Math.floor((e=t%36)/6)/5*255,e%6/5*255]},Tt.rgb.hex=function(t){const e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},Tt.hex.rgb=function(t){const e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];let r=e[0];3===e[0].length&&(r=r.split("").map((t=>t+t)).join(""));const n=parseInt(r,16);return[n>>16&255,n>>8&255,255&n]},Tt.rgb.hcg=function(t){const e=t[0]/255,r=t[1]/255,n=t[2]/255,a=Math.max(Math.max(e,r),n),o=Math.min(Math.min(e,r),n),i=a-o;let s,c;return s=i<1?o/(1-i):0,c=i<=0?0:a===e?(r-n)/i%6:a===r?2+(n-e)/i:4+(e-r)/i,c/=6,c%=1,[360*c,100*i,100*s]},Tt.hsl.hcg=function(t){const e=t[1]/100,r=t[2]/100,n=r<.5?2*e*r:2*e*(1-r);let a=0;return n<1&&(a=(r-.5*n)/(1-n)),[t[0],100*n,100*a]},Tt.hsv.hcg=function(t){const e=t[1]/100,r=t[2]/100,n=e*r;let a=0;return n<1&&(a=(r-n)/(1-n)),[t[0],100*n,100*a]},Tt.hcg.rgb=function(t){const e=t[0]/360,r=t[1]/100,n=t[2]/100;if(0===r)return[255*n,255*n,255*n];const a=[0,0,0],o=e%1*6,i=o%1,s=1-i;let c=0;switch(Math.floor(o)){case 0:a[0]=1,a[1]=i,a[2]=0;break;case 1:a[0]=s,a[1]=1,a[2]=0;break;case 2:a[0]=0,a[1]=1,a[2]=i;break;case 3:a[0]=0,a[1]=s,a[2]=1;break;case 4:a[0]=i,a[1]=0,a[2]=1;break;default:a[0]=1,a[1]=0,a[2]=s}return c=(1-r)*n,[255*(r*a[0]+c),255*(r*a[1]+c),255*(r*a[2]+c)]},Tt.hcg.hsv=function(t){const e=t[1]/100,r=e+t[2]/100*(1-e);let n=0;return r>0&&(n=e/r),[t[0],100*n,100*r]},Tt.hcg.hsl=function(t){const e=t[1]/100,r=t[2]/100*(1-e)+.5*e;let n=0;return r>0&&r<.5?n=e/(2*r):r>=.5&&r<1&&(n=e/(2*(1-r))),[t[0],100*n,100*r]},Tt.hcg.hwb=function(t){const e=t[1]/100,r=e+t[2]/100*(1-e);return[t[0],100*(r-e),100*(1-r)]},Tt.hwb.hcg=function(t){const e=t[1]/100,r=1-t[2]/100,n=r-e;let a=0;return n<1&&(a=(r-n)/(1-n)),[t[0],100*n,100*a]},Tt.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},Tt.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},Tt.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},Tt.gray.hsl=function(t){return[0,0,t[0]]},Tt.gray.hsv=Tt.gray.hsl,Tt.gray.hwb=function(t){return[0,100,t[0]]},Tt.gray.cmyk=function(t){return[0,0,0,t[0]]},Tt.gray.lab=function(t){return[t[0],0,0]},Tt.gray.hex=function(t){const e=255&Math.round(t[0]/100*255),r=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(r.length)+r},Tt.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]};const Ht=Bt;function $t(t){const e=function(){const t={},e=Object.keys(Ht);for(let r=e.length,n=0;n{Et[t]={},Object.defineProperty(Et[t],"channels",{value:Lt[t].channels}),Object.defineProperty(Et[t],"labels",{value:Lt[t].labels});const e=Rt(t);Object.keys(e).forEach((r=>{const n=e[r];Et[t][r]=function(t){const e=function(...e){const r=e[0];if(null==r)return r;r.length>1&&(e=r);const n=t(e);if("object"==typeof n)for(let t=n.length,e=0;e1&&(e=r),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(n)}))}));var Vt=Et;const Nt=gt.exports,qt=Vt,zt=["keyword","gray","hex"],Ut={};for(const t of Object.keys(qt))Ut[[...qt[t].labels].sort().join("")]=t;const Yt={};function Gt(t,e){if(!(this instanceof Gt))return new Gt(t,e);if(e&&e in zt&&(e=null),e&&!(e in qt))throw new Error("Unknown model: "+e);let r,n;if(null==t)this.model="rgb",this.color=[0,0,0],this.valpha=1;else if(t instanceof Gt)this.model=t.model,this.color=[...t.color],this.valpha=t.valpha;else if("string"==typeof t){const e=Nt.get(t);if(null===e)throw new Error("Unable to parse color from string: "+t);this.model=e.model,n=qt[this.model].channels,this.color=e.value.slice(0,n),this.valpha="number"==typeof e.value[n]?e.value[n]:1}else if(t.length>0){this.model=e||"rgb",n=qt[this.model].channels;const r=Array.prototype.slice.call(t,0,n);this.color=Wt(r,n),this.valpha="number"==typeof t[n]?t[n]:1}else if("number"==typeof t)this.model="rgb",this.color=[t>>16&255,t>>8&255,255&t],this.valpha=1;else{this.valpha=1;const e=Object.keys(t);"alpha"in t&&(e.splice(e.indexOf("alpha"),1),this.valpha="number"==typeof t.alpha?t.alpha:0);const n=e.sort().join("");if(!(n in Ut))throw new Error("Unable to parse color from object: "+JSON.stringify(t));this.model=Ut[n];const{labels:a}=qt[this.model],o=[];for(r=0;r(t%360+360)%360)),saturationl:Kt("hsl",1,Xt(100)),lightness:Kt("hsl",2,Xt(100)),saturationv:Kt("hsv",1,Xt(100)),value:Kt("hsv",2,Xt(100)),chroma:Kt("hcg",1,Xt(100)),gray:Kt("hcg",2,Xt(100)),white:Kt("hwb",1,Xt(100)),wblack:Kt("hwb",2,Xt(100)),cyan:Kt("cmyk",0,Xt(100)),magenta:Kt("cmyk",1,Xt(100)),yellow:Kt("cmyk",2,Xt(100)),black:Kt("cmyk",3,Xt(100)),x:Kt("xyz",0,Xt(95.047)),y:Kt("xyz",1,Xt(100)),z:Kt("xyz",2,Xt(108.833)),l:Kt("lab",0,Xt(100)),a:Kt("lab",1),b:Kt("lab",2),keyword(t){return void 0!==t?new Gt(t):qt[this.model].keyword(this.color)},hex(t){return void 0!==t?new Gt(t):Nt.to.hex(this.rgb().round().color)},hexa(t){if(void 0!==t)return new Gt(t);const e=this.rgb().round().color;let r=Math.round(255*this.valpha).toString(16).toUpperCase();return 1===r.length&&(r="0"+r),Nt.to.hex(e)+r},rgbNumber(){const t=this.rgb().color;return(255&t[0])<<16|(255&t[1])<<8|255&t[2]},luminosity(){const t=this.rgb().color,e=[];for(const[r,n]of t.entries()){const t=n/255;e[r]=t<=.04045?t/12.92:((t+.055)/1.055)**2.4}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast(t){const e=this.luminosity(),r=t.luminosity();return e>r?(e+.05)/(r+.05):(r+.05)/(e+.05)},level(t){const e=this.contrast(t);return e>=7?"AAA":e>=4.5?"AA":""},isDark(){const t=this.rgb().color;return(2126*t[0]+7152*t[1]+722*t[2])/1e4<128},isLight(){return!this.isDark()},negate(){const t=this.rgb();for(let e=0;e<3;e++)t.color[e]=255-t.color[e];return t},lighten(t){const e=this.hsl();return e.color[2]+=e.color[2]*t,e},darken(t){const e=this.hsl();return e.color[2]-=e.color[2]*t,e},saturate(t){const e=this.hsl();return e.color[1]+=e.color[1]*t,e},desaturate(t){const e=this.hsl();return e.color[1]-=e.color[1]*t,e},whiten(t){const e=this.hwb();return e.color[1]+=e.color[1]*t,e},blacken(t){const e=this.hwb();return e.color[2]+=e.color[2]*t,e},grayscale(){const t=this.rgb().color,e=.3*t[0]+.59*t[1]+.11*t[2];return Gt.rgb(e,e,e)},fade(t){return this.alpha(this.valpha-this.valpha*t)},opaquer(t){return this.alpha(this.valpha+this.valpha*t)},rotate(t){const e=this.hsl();let r=e.color[0];return r=(r+t)%360,r=r<0?360+r:r,e.color[0]=r,e},mix(t,e){if(!t||!t.rgb)throw new Error('Argument to "mix" was not a Color instance, but rather an instance of '+typeof t);const r=t.rgb(),n=this.rgb(),a=void 0===e?.5:e,o=2*a-1,i=r.alpha()-n.alpha(),s=((o*i==-1?o:(o+i)/(1+o*i))+1)/2,c=1-s;return Gt.rgb(s*r.red()+c*n.red(),s*r.green()+c*n.green(),s*r.blue()+c*n.blue(),r.alpha()*a+n.alpha()*(1-a))}};for(const t of Object.keys(qt)){if(zt.includes(t))continue;const{channels:e}=qt[t];Gt.prototype[t]=function(...e){return this.model===t?new Gt(this):e.length>0?new Gt(e,t):new Gt([...(r=qt[this.model][t].raw(this.color),Array.isArray(r)?r:[r]),this.valpha],t);var r},Gt[t]=function(...r){let n=r[0];return"number"==typeof n&&(n=Wt(r,e)),new Gt(n,t)}}function Jt(t){return function(e){return function(t,e){return Number(t.toFixed(e))}(e,t)}}function Kt(t,e,r){t=Array.isArray(t)?t:[t];for(const n of t)(Yt[n]||(Yt[n]=[]))[e]=r;return t=t[0],function(n){let a;return void 0!==n?(r&&(n=r(n)),a=this[t](),a.color[e]=n,a):(a=this[t]().color[e],r&&(a=r(a)),a)}}function Xt(t){return function(e){return Math.max(0,Math.min(t,e))}}function Wt(t,e){for(let r=0;rObject.assign({},...Object.entries(t??{}).flatMap((([t,e])=>"object"==typeof e?Object.entries(te(e)).map((([e,r])=>({[t+("DEFAULT"===e?"":`-${e}`)]:r}))):[{[`${t}`]:e}]))),ee=(t,e,{usesMediaStrategy:r,darkSelector:n,lightId:a,darkId:o,variablePrefix:i=""})=>{if(!t)return{colors:{},styles:e};const s=te(t);return Object.keys(s).forEach((t=>{const c=t.match(new RegExp(`^(?:(.+)-)?${a}(?:-(.+))?$`));if(c){const a=c[1],l=c[2],u=[a,l].filter((t=>t)).join("-"),h=s[t],d=s[[a,o,l].filter((t=>t)).join("-")];if(h&&d){if(s[u])throw`withModeAwareColors plugin error: adding the '${u}' mode-aware color would overwrite an existing color.`;{const t=Zt(h).rgb().array(),a=t.slice(0,3).join(" "),o=t.length>3?100*t[3]+"%":void 0,c=Zt(d).rgb().array(),l=c.slice(0,3).join(" "),m=c.length>3?100*c[3]+"%":void 0,f=`--color-${i?`${i}-`:""}${u}`,g=`--opacity-${i?`${i}-`:""}${u}`;s[u]=({opacityValue:t})=>`rgb(var(${f}) / ${t?"string"==typeof t&&t.startsWith("var(")?`var(${g}, ${t})`:t:`var(${g}, 1)`})`,e[":root"][f]=a,o&&(e[":root"][g]=o),r?(e["@media (prefers-color-scheme: dark)"][":root"][f]=l,m&&(e["@media (prefers-color-scheme: dark)"][":root"][g]=m)):(e[n][f]=l,m&&(e[n][g]=m))}}}})),{colors:s,styles:e}};const re=(t,e,r={scheme:"content",contrast:0,extend:!1})=>{if(e.primary){const n=X(e,r?.scheme||"content",r?.contrast||0);return((t,{lightId:e,darkId:r}={lightId:"light",darkId:"dark"})=>{const n=Array.isArray(t.darkMode)?"selector"!==t.darkMode[0]:"selector"!==t.darkMode,a=!n&&(Array.isArray(t.darkMode)&&t.darkMode[1]||".dark"),o={":root":{},...n?{"@media (prefers-color-scheme: dark)":{":root":{}}}:{[a]:{}}};if(t.theme?.colors){const{colors:i}=ee(t.theme.colors,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r});t.theme.colors=i}if(t.theme?.extend?.colors){const{colors:i}=ee(t.theme.extend.colors,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r});t.theme.extend.colors=i}if(t.theme?.textColor){const{colors:i}=ee(t.theme.textColor,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r,variablePrefix:"text"});t.theme.textColor=i}if(t.theme?.extend?.textColor){const{colors:i}=ee(t.theme.extend.textColor,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r,variablePrefix:"text"});t.theme.extend.textColor=i}if(t.theme?.backgroundColor){const{colors:i}=ee(t.theme.backgroundColor,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r,variablePrefix:"background"});t.theme.backgroundColor=i}if(t.theme?.extend?.backgroundColor){const{colors:i}=ee(t.theme.extend.backgroundColor,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r,variablePrefix:"background"});t.theme.extend.backgroundColor=i}if(t.theme?.borderColor){const{colors:i}=ee(t.theme.borderColor,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r,variablePrefix:"border"});t.theme.borderColor=i}if(t.theme?.extend?.borderColor){const{colors:i}=ee(t.theme.extend.borderColor,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r,variablePrefix:"border"});t.theme.extend.borderColor=i}if(t.theme?.outlineColor){const{colors:i}=ee(t.theme.outlineColor,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r,variablePrefix:"outline"});t.theme.outlineColor=i}if(t.theme?.extend?.outlineColor){const{colors:i}=ee(t.theme.extend.outlineColor,o,{usesMediaStrategy:n,darkSelector:a,lightId:e,darkId:r,variablePrefix:"outline"});t.theme.extend.outlineColor=i}return{...t,plugins:[...t.plugins||[],Qt((({addBase:t})=>t(o)))]}})({...t,theme:r.extend?{...t.theme||{},extend:{...t.theme?.extend||{},colors:{...t.theme?.extend?.colors||{},...n}}}:{...t.theme||{},colors:{...t.theme?.colors||{},...n}},plugins:[...t.plugins||[],...ft({surfacePrefix:"bg",interactiveSurfacePrefix:"interactive-bg",draggedSurfacePrefix:"dragged-bg",disabledStyles:{textOpacity:.38,backgroundOpacity:.12,colorName:"on-surface"}})]})}throw"A primary color must be specified"};export{re as withMaterialColors}; +//# sourceMappingURL=index.esm.js.map diff --git a/src/TabKeeper.UI.Wasm/tailwind.config.variants.js b/src/TabKeeper.UI.Wasm/tailwind.config.variants.js new file mode 100644 index 0000000..596cdff --- /dev/null +++ b/src/TabKeeper.UI.Wasm/tailwind.config.variants.js @@ -0,0 +1,41 @@ +export function variants({ matchVariant }) { + const defaults = { + // Positional + first: ':first-child', + last: ':last-child', + only: ':only-child', + odd: ':nth-child(odd)', + even: ':nth-child(even)', + 'first-of-type': 'first-of-type', + 'last-of-type': 'last-of-type', + 'only-of-type': 'only-of-type', + // State + visited: 'visited', + target: 'target', + open: '[open]', + // Forms + default: 'default', + checked: 'checked', + indeterminate: 'indeterminate', + 'placeholder-shown': 'placeholder-shown', + autofill: 'autofill', + required: 'required', + valid: 'valid', + invalid: 'invalid', + 'in-range': 'in-range', + 'out-of-range': 'out-of-range', + 'read-only': 'read-only', + // Content + empty: 'empty', + // Interactive + 'focus-within': 'focus-within', + hover: 'hover', + focus: 'focus', + 'focus-visible': 'focus-visible', + active: 'active', + disabled: 'disabled', + } + matchVariant(`parent`, (value) => `:merge(.parent)${value} > &`, { values: defaults }) + matchVariant(`next-input`, (value) => `&:has(+ input:${value})`, { values: defaults }) + matchVariant(`peer-input`, (value) => `input:${value} ~ &`, { values: defaults }) +}; \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/tailwind.extension.json b/src/TabKeeper.UI.Wasm/tailwind.extension.json index 77cfe3c..2d5fd97 100644 --- a/src/TabKeeper.UI.Wasm/tailwind.extension.json +++ b/src/TabKeeper.UI.Wasm/tailwind.extension.json @@ -1,6 +1,27 @@ { - "ConfigurationFile": "tailwind.config.js", - "InputCssFile": "./assets/app.scss", - "OutputCssFile": "./wwwroot/css/app.min.css", + "$schema": "https://raw.githubusercontent.com/theron-wang/VS2022-Editor-Support-for-Tailwind-CSS/refs/heads/main/tailwind.extension.schema.json", + "ConfigurationFiles": [ + { + "Path": "tailwind.config.js", + "IsDefault": true, + "ApplicableLocations": [] + } + ], + "BuildFiles": [], + "PackageConfigurationFile": null, + "CustomRegexes": { + "Razor": { + "Override": false, + "Values": [] + }, + "HTML": { + "Override": false, + "Values": [] + }, + "JavaScript": { + "Override": false, + "Values": [] + } + }, "UseCli": false -} +} \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/wwwroot/i18n/el.json b/src/TabKeeper.UI.Wasm/wwwroot/i18n/el.json new file mode 100644 index 0000000..75fcddb --- /dev/null +++ b/src/TabKeeper.UI.Wasm/wwwroot/i18n/el.json @@ -0,0 +1,24 @@ +{ + "general": { + "home": "Αρχική", + "not-found": { + "title": "Δεν βρέθηκε", + "description": "Συγγνώμη, δεν υπάρχει τίποτα σε αυτήν τη διεύθυνση." + } + }, + "settings": { + "title": "Ρυθμίσεις", + "app.title": "Εφαρμογή", + "theme": { + "title": "Θέμα", + "auto": "Αυτόματο", + "dark": "Σκοτεινό", + "light": "Φωτεινό" + }, + "lang": { + "title": "Γλώσσα", + "en": "English", + "el": "Ελληνικά" + } + } +} diff --git a/src/TabKeeper.UI.Wasm/wwwroot/i18n/en.json b/src/TabKeeper.UI.Wasm/wwwroot/i18n/en.json new file mode 100644 index 0000000..bd42f8a --- /dev/null +++ b/src/TabKeeper.UI.Wasm/wwwroot/i18n/en.json @@ -0,0 +1,24 @@ +{ + "general": { + "home": "Home", + "not-found": { + "title": "Not Found", + "description": "Sorry, there is nothing at this address." + } + }, + "settings": { + "title": "Settings", + "app.title": "Application", + "theme": { + "title": "Theme", + "auto": "Auto", + "dark": "Dark", + "light": "Light" + }, + "lang": { + "title": "Language", + "en": "English", + "el": "Ελληνικά" + } + } +} diff --git a/src/TabKeeper.UI.Wasm/wwwroot/index.html b/src/TabKeeper.UI.Wasm/wwwroot/index.html index c5e2407..3bc00e0 100644 --- a/src/TabKeeper.UI.Wasm/wwwroot/index.html +++ b/src/TabKeeper.UI.Wasm/wwwroot/index.html @@ -1,10 +1,10 @@ - - TabKeeper + + Tab Keeper + + + + + + + + + + - diff --git a/src/TabKeeper.UI.Wasm/wwwroot/js/blazor-decompress.js b/src/TabKeeper.UI.Wasm/wwwroot/js/blazor-decompress.js new file mode 100644 index 0000000..036059c --- /dev/null +++ b/src/TabKeeper.UI.Wasm/wwwroot/js/blazor-decompress.js @@ -0,0 +1,19 @@ +import { BrotliDecode } from './decode.min.js'; + +Blazor.start({ + loadBootResource: function (type, name, defaultUri, integrity) { + if (type !== 'dotnetjs' && location.hostname !== 'localhost' && type !== 'configuration') { + return (async function () { + const response = await fetch(defaultUri + '.br', { cache: 'no-cache' }); + if (!response.ok) { + throw new Error(response.statusText); + } + const originalResponseBuffer = await response.arrayBuffer(); + const originalResponseArray = new Int8Array(originalResponseBuffer); + const decompressedResponseArray = BrotliDecode(originalResponseArray); + const contentType = type === 'dotnetwasm' ? 'application/wasm' : 'application/octet-stream'; + return new Response(decompressedResponseArray, { headers: { 'content-type': contentType } }); + })(); + } + } +}); diff --git a/src/TabKeeper.UI.Wasm/wwwroot/js/index.js b/src/TabKeeper.UI.Wasm/wwwroot/js/index.js new file mode 100644 index 0000000..4a5611b --- /dev/null +++ b/src/TabKeeper.UI.Wasm/wwwroot/js/index.js @@ -0,0 +1,11 @@ +(() => { + const dark = "dark"; + const light = "light"; + const key = "theme"; + + if (localStorage[key] === dark || (!(key in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { + document.documentElement.setAttribute('dark', true) + } else { + document.documentElement.removeAttribute('dark') + } +})(); \ No newline at end of file diff --git a/src/TabKeeper.UI.Wasm/wwwroot/js/indexed-wrapper.js b/src/TabKeeper.UI.Wasm/wwwroot/js/indexed-wrapper.js new file mode 100644 index 0000000..c0d0b34 --- /dev/null +++ b/src/TabKeeper.UI.Wasm/wwwroot/js/indexed-wrapper.js @@ -0,0 +1,284 @@ +class DatabaseDefinition { + /** @type {string} */ + name; + + /** @type {number} */ + version; + + /** @type {ObjectStoreDefinition[]} */ + objectStores; + + /** @param {DatabaseDefinition} definition */ + constructor(definition) { + this.name = definition.name; + this.version = definition.version; + this.objectStores = definition.objectStores.map(s => new ObjectStoreDefinition(s)); + } + + /** + * @param {IDBDatabase} db + * @param {IDBTransaction} transaction + */ + apply(db, transaction) { + const objectStoreNames = [...db.objectStoreNames]; + + // delete stores + objectStoreNames + .filter(objectStore => this.objectStores.find(x => x.name == objectStore) == null) + .forEach(objectStore => db.deleteObjectStore(objectStore)); + + // edit existing stores + this.objectStores + .filter(objectStore => objectStoreNames.find(x => x == objectStore.name) != null) + .forEach(objectStore => objectStore.update(transaction)); + + // add new stores with indexes. + this.objectStores + .filter(objectStore => objectStoreNames.find(x => x == objectStore.name) == null) + .forEach(objectStore => objectStore.create(db)); + } +} + +class IndexDefinition { + /** @type {string} */ + name; + + /** @type {string} */ + keyPath; + + /** @type {?boolean} */ + multiEntry; + + /** @type {?boolean} */ + unique; + + /** @param {IndexDefinition} definition */ + constructor(definition) { + this.name = definition.name; + this.keyPath = definition.keyPath; + this.multiEntry = definition.multiEntry; + this.unique = definition.unique; + } + + /** @param {IDBObjectStore} store */ + create(store) { + store.createIndex(this.name, this.keyPath, { multiEntry: this.multiEntry, unique: this.unique }) + } +} + +class ObjectStoreDefinition { + /** @type {string} */ + name; + + /** @type {string} */ + keyPath; + + /** @type {?boolean} */ + autoIncrement; + + /** @type {IndexDefinition[]} */ + indexes; + + /** @param {ObjectStoreDefinition} definition */ + constructor(definition) { + this.name = definition.name; + this.keyPath = definition.keyPath; + this.autoIncrement = definition.autoIncrement; + this.indexes = definition.indexes.map(i => new IndexDefinition(i)); + } + + /** @param {IDBDatabase} db */ + create(db) { + const store = db.createObjectStore(this.name, { keyPath: this.keyPath, autoIncrement: this.autoIncrement }); + this.indexes.forEach(index => index.create(store)); + } + + /** @param {IDBTransaction} transaction */ + update(transaction) { + const store = transaction.objectStore(this.name); + const indexNames = [...store.indexNames]; + + // Delete indexes + indexNames + .filter(index => !this.containsIndex(index)) + .forEach(index => store.deleteIndex(index)); + + // Create indexes + this.indexes + .filter(index => indexNames.find(x => x == index.name) == null) + .forEach(index => index.create(store)); + } + + /** + * @param {any} index + * @returns {boolean} + */ + containsIndex(index) { + return this.indexes?.find(x => x.name == index) != null; + } +} + +/** + * @param {DatabaseDefinition} definition + * @returns {Promise} + */ +export function open(definition) { + definition = new DatabaseDefinition(definition); + + return new Promise((resolve, reject) => { + const request = indexedDB.open(definition.name, definition.version); + + request.onupgradeneeded = (args) => { + const db = request.result; + const transaction = request.transaction; + definition.apply(db, transaction); + } + request.onblocked = (args) => { + } + request.onsuccess = (args) => { + const db = new Database(request.result); + resolve(db); + }; + request.onerror = (args) => { + reject(request.error); + } + }); +} + +export function databases() { + return indexedDB.databases(); +} + +/** + * @param {string} name + * @returns {boolean} + */ +export function deleteDatabase(name) { + return new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = (args) => { + resolve(request.result == null); + }; + request.onerror = (args) => { + reject(request.error); + }; + }); +} + +class Database { + /** @param db {IDBDatabase} */ + constructor(db) { + this.db = db; + } + + getInfo() { + return { + name: this.db.name, + version: this.db.version, + objectStoreNames: [... this.db.objectStoreNames], + } + }; + + /** + * @param name {string} + * @returns {ObjectStore} + */ + objectStore(name) { + return new ObjectStore(this.db, name); + } + + close() { + this.db.close(); + } +} + +class ObjectStore { + /** + * @param db {IDBDatabase} + * @param store {string} + */ + constructor(db, store) { + this.db = db; + this.store = store; + } + + /** @returns {IDBObjectStore} */ + get objectStore() { + const t = this.db.transaction(this.store, "readwrite"); + return t.objectStore(this.store); + } + + /** + * @template {T} + * @param {IDBRequest} request + * @param {(request:IDBRequest, args:any) => T} onsuccess + * @returns {Promise} + */ + executeRequest(request, onsuccess = null) { + return new Promise((resolve, reject) => { + request.onsuccess = (args) => { + onsuccess != null + ? resolve(onsuccess(request, args)) + : resolve(request.result); + } + request.onerror = (args) => { + reject(request.error); + } + }); + } + + getInfo() { + const objectStore = this.objectStore; + return { + name: objectStore.name, + keyPath: objectStore.keyPath, + autoIncrement: objectStore.autoIncrement, + indexNames: [... objectStore.indexNames], + } + } + + count() { + return this.executeRequest(this.objectStore.count()); + } + + // todo: implement query + get(key) { + return this.executeRequest(this.objectStore.get(key)) + } + + // todo: implement query + //getKey() { + //} + + // todo: implement query + getAll() { + return this.executeRequest(this.objectStore.getAll()); + } + + // todo: implement query + getAllKeys() { + return this.executeRequest(this.objectStore.getAllKeys()); + } + + add(obj) { + return this.executeRequest(this.objectStore.add(obj)); + } + + put(obj) { + return this.executeRequest(this.objectStore.put(obj)); + } + + delete(key) { + return this.executeRequest(this.objectStore.delete(key)); + } + + clear() { + return this.executeRequest(this.objectStore.clear()); + } + + //openCursor() { + //} + + //openKeyCursor() { + //} +} diff --git a/src/TabKeeper.UI.Wasm/wwwroot/js/theme.js b/src/TabKeeper.UI.Wasm/wwwroot/js/theme.js new file mode 100644 index 0000000..f7fdabf --- /dev/null +++ b/src/TabKeeper.UI.Wasm/wwwroot/js/theme.js @@ -0,0 +1,44 @@ +const dark = "dark"; +const light = "light"; +const auto = "auto"; +const key = "theme"; + +export function updateDom() { + if (localStorage[key] === dark || (!(key in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { + document.documentElement.setAttribute('dark', true) + } else { + document.documentElement.removeAttribute('dark') + } +} + +export function toggle() { + if (!(key in localStorage)) return; + + localStorage[key] === light ? setDark() : setLight(); + updateDom(); +} + +export function setDark() { + localStorage[key] = dark; + updateDom(); +} + +export function setLight() { + localStorage[key] = light; + updateDom(); +} + +export function setAuto() { + localStorage.removeItem(key); + updateDom(); +} + +export function getTheme() { + const theme = localStorage[key]; + + if ([dark, light, auto].some(v => v === theme)) + return theme; + + return auto; +} + diff --git a/src/TabKeeper.UI.Wasm/wwwroot/lottie/loading.lottie b/src/TabKeeper.UI.Wasm/wwwroot/lottie/loading.lottie new file mode 100644 index 0000000..e233ccc Binary files /dev/null and b/src/TabKeeper.UI.Wasm/wwwroot/lottie/loading.lottie differ diff --git a/src/TabKeeper.UI.Wasm/wwwroot/lottie/not-found.lottie b/src/TabKeeper.UI.Wasm/wwwroot/lottie/not-found.lottie new file mode 100644 index 0000000..5ddbf9a Binary files /dev/null and b/src/TabKeeper.UI.Wasm/wwwroot/lottie/not-found.lottie differ diff --git a/src/TabKeeper.UI/People/PersonViewModel.cs b/src/TabKeeper.UI/People/PersonViewModel.cs deleted file mode 100644 index b14472f..0000000 --- a/src/TabKeeper.UI/People/PersonViewModel.cs +++ /dev/null @@ -1,104 +0,0 @@ -using Core.Reactive; -using TabKeeper.Tabs; - -namespace TabKeeper.People; - -public sealed class PersonViewModel : RxObject -{ - private readonly SourceCache products; - private Person person; - private decimal total; - - public Uuid PersonId => person.Id; - - public string Name - { - get => person.Name; - set => SetValidateAndRaise(ref person, person with { Name = value }); - } - - public decimal Total => total; - - public IEnumerable ProductIds => products.Keys; - - public PersonViewModel() : this(new Person { Id = Uuid.NewUuid() }) - { - } - - public PersonViewModel(Person person) - { - this.person = person; - products = new(p => p.ProductId); - - products - .Connect() - .AutoRefresh(x => x.Total) // will refresh when product total has changed. - .AutoRefresh(x => x.Divisor) // will refresh when product total has changed. - .Transform(x => new ProductProxy(x)) - .DisposeMany() - .QueryWhenChanged(query => query.Items - .Sum(proxy => proxy.Total) - ) - // Get the latest changes and compute the sum. - - //.QueryWhenChanged(query => query.Items - // .Select(product => product.TotalSubs > 0 ? product.Total / product.TotalSubs : 0) - // .Sum(division => division) - //) // Get the latest changes and compute the sum. - .Subscribe(total => SetAndRaise(ref this.total, total, nameof(Total))) // Set our total. - .DisposeWith(Disposables); - } - - public None RegisterProduct(ProductViewModel product) - { - products.AddOrUpdate(product); - return None.Value; - } - - public None UnRegisterProduct(ProductViewModel product) - { - products.Remove(product); - return None.Value; - } - - public None ToggleProduct(ProductViewModel product) - { - return HasProduct(product) ? UnRegisterProduct(product) : RegisterProduct(product); - } - - public bool HasProduct(Uuid productId) - { - return products.Lookup(productId).HasValue; - } - - public bool HasProduct(ProductViewModel product) - { - return HasProduct(product.ProductId); - } - - public override void Dispose() - { - products.Clear(); - products.Dispose(); - base.Dispose(); - } -} - -file sealed class ProductProxy : IDisposable -{ - private readonly IDisposable sub; - private readonly ProductViewModel product; - - public decimal Total => product.Divisor > 0 ? product.Total / product.Divisor : 0; - - public ProductProxy(ProductViewModel product) - { - this.product = product; - sub = this.product.WhenTotalChanged.Subscribe(); - } - - public void Dispose() - { - sub.Dispose(); - } -} diff --git a/src/TabKeeper.UI/Preferences.cs b/src/TabKeeper.UI/Preferences.cs new file mode 100644 index 0000000..40d2759 --- /dev/null +++ b/src/TabKeeper.UI/Preferences.cs @@ -0,0 +1,34 @@ +using Core.Preferences.Builders; +using Core.Preferences.Controls; + +namespace TabKeeper; + +public static class Preferences +{ + public const string Language = "lang"; + + public const string Theme = "theme"; + + public static PreferenceScreen Screen { get; } = PreferenceScreenBuilder + .CreateEmpty() + .AddCategory(b => b + .WithTitle("settings.app.title") + .AddListBox(new() + { + Key = Preferences.Theme, + Title = "settings.theme.title", + AllowedValues = ["auto", "dark", "light"], + DefaultValue = "auto", + SummaryProvider = value => $"settings.theme.{value}", + }) + .AddListBox(new() + { + Key = Preferences.Language, + Title = "settings.lang.title", + AllowedValues = ["en", "el"], + DefaultValue = "en", + SummaryProvider = value => $"settings.lang.{value}", + }) + ) + .Build(); +} diff --git a/src/TabKeeper.UI/TabKeeper.UI.csproj b/src/TabKeeper.UI/TabKeeper.UI.csproj index 001b71f..e38cc2c 100644 --- a/src/TabKeeper.UI/TabKeeper.UI.csproj +++ b/src/TabKeeper.UI/TabKeeper.UI.csproj @@ -1,12 +1,13 @@  - net8.0 + net9.0 TabKeeper - + + diff --git a/src/TabKeeper.UI/Tabs/ProductViewModel.cs b/src/TabKeeper.UI/Tabs/ProductViewModel.cs deleted file mode 100644 index a34cb13..0000000 --- a/src/TabKeeper.UI/Tabs/ProductViewModel.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Core.Reactive; -using DynamicData.Binding; -using System.Reactive.Subjects; - -namespace TabKeeper.Tabs; - -public sealed class ProductViewModel : RxObject -{ - private readonly BehaviorSubject totalSubject; - private Product product; - private int divisor = 0; - - public Uuid ProductId => product.Id; - - public string Name - { - get => product.Name; - set => SetValidateAndRaise(ref product, product with { Name = value }); - } - - public decimal Price - { - get => product.Price; - set => SetValidateAndRaise(ref product, product with { Price = value }, nameof(Price), nameof(Total)); - } - - public decimal Quantity - { - get => product.Quantity; - set => SetValidateAndRaise(ref product, product with { Quantity = value }, nameof(Quantity), nameof(Total)); - } - - public decimal Total => product.Total; - - public int Divisor => divisor; - - public IObservable WhenTotalChanged => - Observable.Defer(() => - { - Interlocked.Increment(ref divisor); - RaisePropertyChanged(nameof(Divisor)); - return totalSubject.Finally(() => - { - Interlocked.Decrement(ref divisor); - RaisePropertyChanged(nameof(Divisor)); - }); - }); - - public ProductViewModel() : this(new() { Id = Uuid.NewUuid() }) - { - } - - public ProductViewModel(Product product) - { - this.product = product; - totalSubject = new(product.Total); - totalSubject.DisposeWith(Disposables); - this.WhenValueChanged(x => x.Total).Subscribe(totalSubject); - } - - public override void Dispose() - { - if (!totalSubject.IsDisposed) - totalSubject.OnCompleted(); - - base.Dispose(); - } -} diff --git a/src/TabKeeper.UI/Tabs/TabPersonViewModel.cs b/src/TabKeeper.UI/Tabs/TabPersonViewModel.cs new file mode 100644 index 0000000..323ff63 --- /dev/null +++ b/src/TabKeeper.UI/Tabs/TabPersonViewModel.cs @@ -0,0 +1,110 @@ +using Core.Reactive; +using TabKeeper.People; + +namespace TabKeeper.Tabs; + +public sealed class TabPersonViewModel : RxObject +{ + private readonly SourceCache products; + private readonly TabPerson tab; + private decimal total; + + public TabPerson Tab => tab; + + public Person Person + { + get => tab.Person; + set { + Tab.Person = value; + RaisePropertyChanged(nameof(Person)); + } + } + + public Uuid PersonId => tab.Person.Id; + + public string Name => Person.Name; + + public decimal Total + { + get => total; + private set => SetAndRaise(ref total, value); + } + + public TabPersonViewModel() : this(new TabPerson(new())) + { + } + + public TabPersonViewModel(TabPerson tab) + { + this.tab = tab; + products = new(p => p.ProductId); + + products + .Connect() + .AutoRefresh(x => x.Total) + .AutoRefresh(x => x.Participants) + .OnItemAdded(x => tab.ProductIds.Add(x.ProductId)) + .OnItemRemoved(x => tab.ProductIds.Remove(x.ProductId)) + .Transform(x => new ProductProxy(PersonId, x)) + .DisposeMany() + // Get the latest changes and compute the sum. + .QueryWhenChanged(query => query.Items + .Sum(proxy => proxy.Total) + ) + .Subscribe(total => Total = total) + .DisposeWith(Disposables); + } + + public None RegisterProduct(TabProductViewModel product) + { + products.AddOrUpdate(product); + return None.Value; + } + + public None UnRegisterProduct(TabProductViewModel product) + { + products.Remove(product); + return None.Value; + } + + public None ToggleProduct(TabProductViewModel product) + { + return HasProduct(product) ? UnRegisterProduct(product) : RegisterProduct(product); + } + + public bool HasProduct(Uuid productId) + { + return products.Lookup(productId).HasValue; + } + + public bool HasProduct(TabProductViewModel product) + { + return HasProduct(product.ProductId); + } + + public override void Dispose() + { + products.Clear(); + products.Dispose(); + base.Dispose(); + } +} + +file sealed class ProductProxy : IDisposable +{ + private readonly IDisposable sub; + private readonly TabProductViewModel product; + + public decimal Total { get; private set; } + + public ProductProxy(Uuid personId, TabProductViewModel product) + { + this.product = product; + sub = this.product.Participate(personId).Subscribe(total => Total = total); + } + + public void Dispose() + { + sub.Dispose(); + } +} diff --git a/src/TabKeeper.UI/Tabs/TabProductViewModel.cs b/src/TabKeeper.UI/Tabs/TabProductViewModel.cs new file mode 100644 index 0000000..b5db608 --- /dev/null +++ b/src/TabKeeper.UI/Tabs/TabProductViewModel.cs @@ -0,0 +1,81 @@ +using Core.Reactive; +using DynamicData.Binding; + +namespace TabKeeper.Tabs; + +public sealed class TabProductViewModel : RxObject +{ + private TabProduct product; + private int participants = 0; + private readonly HashSet participantIds = []; + + public TabProduct Product + { + get => product; + set => SetAndRaise(ref product, value); + } + + public Uuid ProductId => product.Id; + + public string Name + { + get => product.Name; + set => SetAndRaise(ref product, product with { Name = value }); + } + + public decimal Price + { + get => product.Price; + set => SetAndRaise(ref product, product with { Price = value }, nameof(Price), nameof(Total)); + } + + public decimal Quantity + { + get => product.Quantity; + set => SetAndRaise(ref product, product with { Quantity = value }, nameof(Quantity), nameof(Total)); + } + + public decimal Total => product.Total; + + public int Participants => participants; + + public IEnumerable ParticipantIds => participantIds; + + public TabProductViewModel() : this(new() { Id = Uuid.NewUuid() }) + { + } + + public TabProductViewModel(TabProduct product) + { + this.product = product; + } + + public IObservable Participate(Uuid participantId) => + Observable.Defer(() => + { + if (participantIds.Add(participantId)) + { + RaisePropertyChanged(nameof(ParticipantIds)); + Interlocked.Increment(ref participants); + RaisePropertyChanged(nameof(Participants)); + } + return this + .WhenAnyPropertyChanged(nameof(Total), nameof(Participants)) + .Prepend(this) + .Select(static vm => vm!.Participants > 0 ? vm!.Total / vm!.Participants : 0) + .Finally(() => + { + if (participantIds.Remove(participantId)) + { + RaisePropertyChanged(nameof(ParticipantIds)); + Interlocked.Decrement(ref participants); + RaisePropertyChanged(nameof(Participants)); + } + }); + }); + + public void ProductUpdated() + { + RaisePropertiesChanged(nameof(Name), nameof(Price), nameof(Quantity), nameof(Total)); + } +} diff --git a/src/TabKeeper.UI/Tabs/TabViewModel.cs b/src/TabKeeper.UI/Tabs/TabViewModel.cs index 10abbe1..2e4f4d7 100644 --- a/src/TabKeeper.UI/Tabs/TabViewModel.cs +++ b/src/TabKeeper.UI/Tabs/TabViewModel.cs @@ -1,6 +1,6 @@ +using Core.Common.Mixins; using Core.Reactive; using DynamicData.Binding; -using TabKeeper.People; namespace TabKeeper.Tabs; @@ -8,76 +8,86 @@ public sealed class TabViewModel : RxObject { public Tab Tab { get; } - private readonly SourceCache people = new(p => p.PersonId); - private readonly SourceCache products = new(p => p.ProductId); + private readonly SourceCache products = new(p => p.ProductId); + private readonly SourceCache people = new(p => p.PersonId); public TabViewModel(Tab tab) { Tab = tab; + products.AddOrUpdate(tab.Products.Select(x => new TabProductViewModel(x))); + people.Edit(people => + { + foreach (var personVm in tab.People.Select(person => new TabPersonViewModel(person))) + { + people.AddOrUpdate(personVm); + foreach (var productVm in products.Items.IntersectBy(personVm.Tab.ProductIds, p => p.ProductId)) + { + personVm.RegisterProduct(productVm); + } + } + }); + people .Connect() .AutoRefresh() + .OnItemAdded(item => tab.People.AddOrUpdate(item.Tab)) + .OnItemRefreshed(item => tab.People.AddOrUpdate(item.Tab)) + //.OnItemUpdated((item, _) => tab.People.AddOrUpdate(item.Tab)) + .OnItemRemoved(item => tab.People.Remove(item.Tab)) .DisposeMany() .BindToObservableList(out var peopleList) .Subscribe(_ => RaisePropertyChanged(nameof(People))) - .DisposeWith(Disposables); + .DisposeWith(this); + People = peopleList; products .Connect() - .AutoRefresh(x => x.Total) - .AutoRefresh(x => x.Divisor) + .AutoRefresh() + .OnItemAdded(item => tab.Products.AddOrUpdate(item.Product)) + .OnItemRefreshed(item => tab.Products.AddOrUpdate(item.Product)) + //.OnItemUpdated((item, _) => tab.Products.AddOrUpdate(item.Product)) + .OnItemRemoved(item => tab.Products.Remove(item.Product)) .DisposeMany() .BindToObservableList(out var productsList) .Subscribe(_ => RaisePropertyChanged(nameof(Products))) - .DisposeWith(Disposables); + .DisposeWith(this); - People = peopleList; Products = productsList; + } - products.AddOrUpdate(tab.Products.Select(x => new ProductViewModel(x))); - people.Edit(people => - { - foreach (var personTab in tab.People) - { - var vm = new PersonViewModel(personTab.Person); - people.AddOrUpdate(vm); - foreach (var productId in personTab.ProductIds) - { - var l = products.Lookup(productId); - if (l.HasValue) - { - vm.RegisterProduct(l.Value); - } - } - } - }); + public IObservableList Products { get; } - foreach (var product in tab.Products) - { - } - } + public IObservableList People { get; } - public IObservableList Products { get; } + public decimal Total => products.Items.Sum(x => x.Total); - public IObservableList People { get; } + public TabProductViewModel? GetProduct(Uuid productId) + { + return products.Lookup(productId) is { HasValue: true, Value: { } person } ? person : null; + } - public void AddProduct(ProductViewModel product) + public void AddProduct(TabProductViewModel product) { products.AddOrUpdate(product); } - public void RemoveProduct(ProductViewModel product) + public void RemoveProduct(TabProductViewModel product) { products.Remove(product); } - public void AddPerson(PersonViewModel person) + public TabPersonViewModel? GetPerson(Uuid personId) + { + return people.Lookup(personId) is { HasValue: true, Value: { } person } ? person : null; + } + + public void AddPerson(TabPersonViewModel person) { people.AddOrUpdate(person); } - public void RemovePerson(PersonViewModel person) + public void RemovePerson(TabPersonViewModel person) { people.Remove(person); } diff --git a/src/TabKeeper.UI/Tabs/TabsViewModel.cs b/src/TabKeeper.UI/Tabs/TabsViewModel.cs deleted file mode 100644 index db5d32f..0000000 --- a/src/TabKeeper.UI/Tabs/TabsViewModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Core.Reactive; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace TabKeeper.Tabs; - -public sealed class TabsViewModel : RxObject -{ - public TabsViewModel() - { - } -} diff --git a/src/TabKeeper/People/PeopleCollection.cs b/src/TabKeeper/People/PeopleCollection.cs new file mode 100644 index 0000000..e50f165 --- /dev/null +++ b/src/TabKeeper/People/PeopleCollection.cs @@ -0,0 +1,18 @@ +using Core; +using Core.Abstractions; +using FluentValidation; + +namespace TabKeeper.People; + +public sealed class PeopleCollection : DictionaryCollection, IValid +{ + public override Uuid GetKeyForItem(Person item) + { + return item.Id; + } + + public static IValidator Validator { get; } = InlineValidator.For(data => + { + data.RuleForEach(x => x).Valid(); + }); +} diff --git a/src/TabKeeper/People/Person.cs b/src/TabKeeper/People/Person.cs index 52a0118..ae44926 100644 --- a/src/TabKeeper/People/Person.cs +++ b/src/TabKeeper/People/Person.cs @@ -1,18 +1,29 @@ using Core; using Core.Abstractions; using FluentValidation; +using System.Text.Json.Serialization; namespace TabKeeper.People; -public sealed record Person : IValid, IEquatable +public sealed record Person : IEntity, ISnapshotCode, IValid { - public required Uuid Id { get; init; } + public Uuid Id { get; init; } - public string Name { get; init; } = string.Empty; + public string Name { get; set; } = string.Empty; - public bool Equals(Uuid other) + public Person() : this(Uuid.NewUuid()) { - return Id.Equals(other); + } + + [JsonConstructor] + public Person(Uuid id) + { + Id = id; + } + + public int GetSnapshotCode() + { + return HashCode.Combine(Id, Name); } public static IValidator Validator { get; } = InlineValidator.For(data => @@ -21,7 +32,6 @@ public bool Equals(Uuid other) .NotEmpty(); data.RuleFor(x => x.Name) - .NotEmpty() - .MaximumLength(100); + .Length(1, 100); }); } diff --git a/src/TabKeeper/TabKeeper.csproj b/src/TabKeeper/TabKeeper.csproj index 2d324cf..4a92aca 100644 --- a/src/TabKeeper/TabKeeper.csproj +++ b/src/TabKeeper/TabKeeper.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 diff --git a/src/TabKeeper/Tabs/PersonTab.cs b/src/TabKeeper/Tabs/PersonTab.cs deleted file mode 100644 index d97c65c..0000000 --- a/src/TabKeeper/Tabs/PersonTab.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Core; -using TabKeeper.People; - -namespace TabKeeper.Tabs; - -public sealed record PersonTab -{ - public Person Person { get; } - - public HashSet ProductIds { get; init; } = []; - - public PersonTab(Person person) - { - Person = person; - } - - public override int GetHashCode() - { - return Person.Id.GetHashCode(); - } - - public bool Equals(PersonTab? other) - { - return Person.Id.Equals(other?.Person.Id); - } -} diff --git a/src/TabKeeper/Tabs/Product.cs b/src/TabKeeper/Tabs/Product.cs deleted file mode 100644 index 975fd2b..0000000 --- a/src/TabKeeper/Tabs/Product.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Core; -using Core.Abstractions; -using FluentValidation; - -namespace TabKeeper.Tabs; - -public sealed record Product : IValid -{ - public required Uuid Id { get; init; } - - public string Name { get; init; } = string.Empty; - - public decimal Price { get; init; } - - public decimal Quantity { get; init; } = 1; - - public decimal Total - => Price is < 0 || Quantity is < 0 ? 0 : Price * Quantity; - - public static IValidator Validator { get; } = InlineValidator.For(data => - { - data.RuleFor(x => x.Id) - .NotEmpty(); - - data.RuleFor(x => x.Name) - .Length(3, 100); - - data.RuleFor(x => x.Price) - .GreaterThan(0); - - data.RuleFor(x => x.Quantity) - .GreaterThan(0); - }); -} diff --git a/src/TabKeeper/Tabs/Tab.cs b/src/TabKeeper/Tabs/Tab.cs index a9d620f..bafdf37 100644 --- a/src/TabKeeper/Tabs/Tab.cs +++ b/src/TabKeeper/Tabs/Tab.cs @@ -1,29 +1,62 @@ using Core; -using System.Text.Json; +using Core.Abstractions; +using FluentValidation; +using System.Text.Json.Serialization; namespace TabKeeper.Tabs; -public sealed record Tab +/// +/// Represents a tab. +/// +public sealed record Tab : IEntity, IValid { - public required Uuid Id { get; init; } + public Uuid Id { get; init; } - public required string Name { get; set; } + public string Name { get; set; } = string.Empty; - public string Place { get; set; } = string.Empty; + public string? Place { get; set; } + + public Uuid? PayerId { get; set; } public DateOnly? Date { get; set; } - public HashSet Products { get; set; } = []; + public bool IsLocked { get; set; } + + public TabProductCollection Products { get; set; } = []; - public HashSet People { get; set; } = []; + public TabPeopleCollection People { get; set; } = []; - public override string ToString() + public Tab() : this(Uuid.NewUuid()) { - return JsonSerializer.Serialize(this); } - public string Formatted() + [JsonConstructor] + public Tab(Uuid id) { - return Place is { Length: > 0 } ? $"{Name} @ {Place}" : Name; + Id = id; } + + public static IValidator Validator { get; } = InlineValidator.For(data => + { + data.RuleFor(x => x.Id) + .NotEmpty(); + + data.RuleFor(x => x.Name) + .Length(1, 100); + + data.RuleFor(x => x.Place) + .MaximumLength(100); + + data.RuleFor(x => x.PayerId) + .NotEmpty() + .When(x => x.PayerId is { }); + + data.RuleFor(x => x.Products) + .Valid() + .Configure(c => c.RuleSets = ["Lists", "Products"]); + + data.RuleFor(x => x.People) + .Valid() + .Configure(c => c.RuleSets = ["Lists", "People"]); + }); } diff --git a/src/TabKeeper/Tabs/TabPeopleCollection.cs b/src/TabKeeper/Tabs/TabPeopleCollection.cs new file mode 100644 index 0000000..cbe0ca8 --- /dev/null +++ b/src/TabKeeper/Tabs/TabPeopleCollection.cs @@ -0,0 +1,18 @@ +using Core; +using Core.Abstractions; +using FluentValidation; + +namespace TabKeeper.Tabs; + +public sealed class TabPeopleCollection : DictionaryCollection, IValid +{ + public override Uuid GetKeyForItem(TabPerson item) + { + return item.Person.Id; + } + + public static IValidator Validator { get; } = InlineValidator.For(data => + { + data.RuleForEach(x => x).Valid(); + }); +} diff --git a/src/TabKeeper/Tabs/TabPerson.cs b/src/TabKeeper/Tabs/TabPerson.cs new file mode 100644 index 0000000..8060ecd --- /dev/null +++ b/src/TabKeeper/Tabs/TabPerson.cs @@ -0,0 +1,60 @@ +using Core; +using Core.Abstractions; +using FluentValidation; +using TabKeeper.People; + +namespace TabKeeper.Tabs; + +/// +/// Represents a tab of a person. +/// +public sealed record TabPerson : ISnapshotCode, IValid +{ + /// + /// The person this tab belongs to. + /// + public Person Person { get; set; } + + /// + /// A list of product ids that this person shares with other people. + /// + public HashSet ProductIds { get; init; } = []; + + /// + /// A list of products that belong to this person only. + /// + public TabProductCollection Products { get; init; } = []; + + /// + /// Initialize a new instance of providing the person. + /// + public TabPerson(Person person) + { + Person = person; + } + + /// + public int GetSnapshotCode() + { + return HashCode.Combine(Person.GetSnapshotCode(), ProductIds.GetAggregateHashCode(), Products.GetSnapshotCode()); + } + + /// + public override int GetHashCode() + { + return HashCode.Combine(Person.Id); + } + + /// + public bool Equals(TabPerson? other) + { + return Person.Equals(other?.Person); + } + + public static IValidator Validator { get; } = InlineValidator.For(data => + { + data.RuleFor(x => x.Person).Valid(); + data.RuleForEach(x => x.ProductIds).NotEmpty(); + data.RuleFor(x => x.Products).Valid(); + }); +} diff --git a/src/TabKeeper/Tabs/TabProduct.cs b/src/TabKeeper/Tabs/TabProduct.cs new file mode 100644 index 0000000..6682868 --- /dev/null +++ b/src/TabKeeper/Tabs/TabProduct.cs @@ -0,0 +1,50 @@ +using Core; +using Core.Abstractions; +using FluentValidation; +using System.Text.Json.Serialization; + +namespace TabKeeper.Tabs; + +public sealed record TabProduct : IEntity, ISnapshotCode, IValid +{ + public Uuid Id { get; init; } + + public string Name { get; set; } = string.Empty; + + public decimal Price { get; set; } + + public decimal Quantity { get; set; } = 1; + + public decimal Total + => Price is < 0 || Quantity is < 0 ? 0 : Price * Quantity; + + public TabProduct() : this(Uuid.NewUuid()) + { + } + + [JsonConstructor] + public TabProduct(Uuid id) + { + Id = id; + } + + public int GetSnapshotCode() + { + return HashCode.Combine(Id, Name, Price, Quantity); + } + + public static IValidator Validator { get; } = InlineValidator.For(data => + { + data.RuleFor(x => x.Id) + .NotEmpty(); + + data.RuleFor(x => x.Name) + .Length(1, 100); + + data.RuleFor(x => x.Price) + .GreaterThan(0); + + data.RuleFor(x => x.Quantity) + .GreaterThan(0); + }); +} diff --git a/src/TabKeeper/Tabs/TabProductCollection.cs b/src/TabKeeper/Tabs/TabProductCollection.cs new file mode 100644 index 0000000..a077cb1 --- /dev/null +++ b/src/TabKeeper/Tabs/TabProductCollection.cs @@ -0,0 +1,18 @@ +using Core; +using Core.Abstractions; +using FluentValidation; + +namespace TabKeeper.Tabs; + +public sealed class TabProductCollection : DictionaryCollection, IValid +{ + public override Uuid GetKeyForItem(TabProduct item) + { + return item.Id; + } + + public static IValidator Validator { get; } = InlineValidator.For(data => + { + data.RuleForEach(x => x).Valid(); + }); +} diff --git a/tests/TabKeeper.UI.UnitTests/People/PersonViewModelTests.cs b/tests/TabKeeper.UI.UnitTests/People/PersonViewModelTests.cs index 5ca30c2..c14962d 100644 --- a/tests/TabKeeper.UI.UnitTests/People/PersonViewModelTests.cs +++ b/tests/TabKeeper.UI.UnitTests/People/PersonViewModelTests.cs @@ -13,11 +13,11 @@ public sealed class PersonViewModelTests public void Should_Change_Total_For_One_Person() { // Arrange - var salad = new ProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Salad", Price = 5 }); - var chips = new ProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Chips", Price = 10 }); - var meat = new ProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Meat", Price = 15 }); + var salad = new TabProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Salad", Price = 5 }); + var chips = new TabProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Chips", Price = 10 }); + var meat = new TabProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Meat", Price = 15 }); - var viewModel = new PersonViewModel(new() { Id = Uuid.NewUuid(), Name = "Panos" }); + var viewModel = new TabPersonViewModel(new() { Id = Uuid.NewUuid(), Name = "Panos" }); decimal total = 0; viewModel.WhenValueChanged(x => x.Total).Subscribe(x => total = x); @@ -49,13 +49,13 @@ public void Should_Change_Total_For_One_Person() public void Should_Change_Totals_For_Many_People() { // Arrange - var salad = new ProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Salad", Price = 6 }); - var chips = new ProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Chips", Price = 6 }); - var meat = new ProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Meat", Price = 15 }); + var salad = new TabProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Salad", Price = 6 }); + var chips = new TabProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Chips", Price = 6 }); + var meat = new TabProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Meat", Price = 15 }); - var panos = new PersonViewModel(new() { Id = Uuid.NewUuid(), Name = "Panos" }); - var john = new PersonViewModel(new() { Id = Uuid.NewUuid(), Name = "John" }); - var george = new PersonViewModel(new() { Id = Uuid.NewUuid(), Name = "George" }); + var panos = new TabPersonViewModel(new() { Id = Uuid.NewUuid(), Name = "Panos" }); + var john = new TabPersonViewModel(new() { Id = Uuid.NewUuid(), Name = "John" }); + var george = new TabPersonViewModel(new() { Id = Uuid.NewUuid(), Name = "George" }); decimal panosTotal = 0, johnTotal = 0, georgeTotal = 0; @@ -115,11 +115,11 @@ public void Should_Change_Totals_For_Many_People() public void Should_Change_Totals_After_Removing_People_Or_Product() { // Arrange - var salad = new ProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Salad", Price = 9 }); + var salad = new TabProductViewModel(new() { Id = Uuid.NewUuid(), Name = "Salad", Price = 9 }); - var panos = new PersonViewModel(new() { Id = Uuid.NewUuid(), Name = "Panos" }); - var john = new PersonViewModel(new() { Id = Uuid.NewUuid(), Name = "John" }); - var george = new PersonViewModel(new() { Id = Uuid.NewUuid(), Name = "George" }); + var panos = new TabPersonViewModel(new() { Id = Uuid.NewUuid(), Name = "Panos" }); + var john = new TabPersonViewModel(new() { Id = Uuid.NewUuid(), Name = "John" }); + var george = new TabPersonViewModel(new() { Id = Uuid.NewUuid(), Name = "George" }); decimal panosTotal = 0, johnTotal = 0, georgeTotal = 0; diff --git a/tests/TabKeeper.UI.UnitTests/TabKeeper.UI.UnitTests.csproj b/tests/TabKeeper.UI.UnitTests/TabKeeper.UI.UnitTests.csproj index 214ffff..1770263 100644 --- a/tests/TabKeeper.UI.UnitTests/TabKeeper.UI.UnitTests.csproj +++ b/tests/TabKeeper.UI.UnitTests/TabKeeper.UI.UnitTests.csproj @@ -1,23 +1,17 @@ - + - net8.0 + net9.0 false true - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - + + + + + diff --git a/tests/TabKeeper.UI.UnitTests/Tabs/ProductViewModelTests.cs b/tests/TabKeeper.UI.UnitTests/Tabs/ProductViewModelTests.cs index 9f37b03..ea3ab65 100644 --- a/tests/TabKeeper.UI.UnitTests/Tabs/ProductViewModelTests.cs +++ b/tests/TabKeeper.UI.UnitTests/Tabs/ProductViewModelTests.cs @@ -16,7 +16,7 @@ public sealed class ProductViewModelTests public void Should_Change_Product_Properties() { // Arrange - var product = new Product + var product = new TabProduct { Id = Uuid.NewUuid(), Name = "Test", @@ -24,7 +24,7 @@ public void Should_Change_Product_Properties() Quantity = 1 }; - var viewModel = new ProductViewModel(product); + var viewModel = new TabProductViewModel(product); var propertyChangedFired = false; var propertyChangingFired = false; diff --git a/version.json b/version.json deleted file mode 100644 index 3839403..0000000 --- a/version.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.1-dev", - "release": { - "firstUnstableTag": "dev" - }, - "publicReleaseRefSpec": [ - "^refs/heads/main$", - "^refs/heads/dev$" - ], - "pathFilters": [ - ":/src/" - ], - "cloudBuild": { - "setVersionVariables": true, - "buildNumber": { - "enabled": false - } - } -} \ No newline at end of file