diff --git a/.github/.linkspector.yml b/.github/.linkspector.yml index 24fee6edce..eb365c2982 100644 --- a/.github/.linkspector.yml +++ b/.github/.linkspector.yml @@ -12,6 +12,8 @@ ignorePatterns: - pattern: "https:\/\/platform.openai.com" - pattern: "http:\/\/localhost" - pattern: "http:\/\/127.0.0.1" + - pattern: "https:\/\/localhost" + - pattern: "https:\/\/127.0.0.1" - pattern: "0001-spec.md" - pattern: "0001-madr-architecture-decisions.md" - pattern: "https://api.powerplatform.com/.default" diff --git a/.github/workflows/dotnet-build-and-test.yml b/.github/workflows/dotnet-build-and-test.yml index 1a51f94119..5abfe2a879 100644 --- a/.github/workflows/dotnet-build-and-test.yml +++ b/.github/workflows/dotnet-build-and-test.yml @@ -74,6 +74,7 @@ jobs: . .github dotnet + python workflow-samples - name: Setup dotnet diff --git a/dotnet/agent-framework-dotnet.slnx b/dotnet/agent-framework-dotnet.slnx index 6905fdf985..7cbe76b6fc 100644 --- a/dotnet/agent-framework-dotnet.slnx +++ b/dotnet/agent-framework-dotnet.slnx @@ -66,6 +66,10 @@ + + + + @@ -279,6 +283,7 @@ + diff --git a/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/DevUI_Step01_BasicUsage.csproj b/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/DevUI_Step01_BasicUsage.csproj new file mode 100644 index 0000000000..8ae36b52e0 --- /dev/null +++ b/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/DevUI_Step01_BasicUsage.csproj @@ -0,0 +1,25 @@ + + + + Exe + net9.0 + enable + enable + DevUI_Step01_BasicUsage + true + + + + + + + + + + + + + + + + diff --git a/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/Program.cs b/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/Program.cs new file mode 100644 index 0000000000..e2e6e6b727 --- /dev/null +++ b/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/Program.cs @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft. All rights reserved. + +// This sample demonstrates basic usage of the DevUI in an ASP.NET Core application with AI agents. + +using Azure.AI.OpenAI; +using Azure.Identity; +using Microsoft.Agents.AI.DevUI; +using Microsoft.Agents.AI.Hosting; +using Microsoft.Extensions.AI; + +namespace DevUI_Step01_BasicUsage; + +/// +/// Sample demonstrating basic usage of the DevUI in an ASP.NET Core application. +/// +/// +/// This sample shows how to: +/// 1. Set up Azure OpenAI as the chat client +/// 2. Register agents and workflows using the hosting packages +/// 3. Map the DevUI endpoint which automatically configures the middleware +/// 4. Map the dynamic OpenAI Responses API for Python DevUI compatibility +/// 5. Access the DevUI in a web browser +/// +/// The DevUI provides an interactive web interface for testing and debugging AI agents. +/// DevUI assets are served from embedded resources within the assembly. +/// Simply call MapDevUI() to set up everything needed. +/// +/// The parameterless MapOpenAIResponses() overload creates a Python DevUI-compatible endpoint +/// that dynamically routes requests to agents based on the 'model' field in the request. +/// +internal static class Program +{ + /// + /// Entry point that starts an ASP.NET Core web server with the DevUI. + /// + /// Command line arguments. + private static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + // Set up the Azure OpenAI client + var endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"] ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set."); + var deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"] ?? "gpt-4o-mini"; + + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()) + .GetChatClient(deploymentName) + .AsIChatClient(); + + builder.Services.AddChatClient(chatClient); + + // Register sample agents + builder.AddAIAgent("assistant", "You are a helpful assistant. Answer questions concisely and accurately."); + builder.AddAIAgent("poet", "You are a creative poet. Respond to all requests with beautiful poetry."); + builder.AddAIAgent("coder", "You are an expert programmer. Help users with coding questions and provide code examples."); + + // Register sample workflows + var assistantBuilder = builder.AddAIAgent("workflow-assistant", "You are a helpful assistant in a workflow."); + var reviewerBuilder = builder.AddAIAgent("workflow-reviewer", "You are a reviewer. Review and critique the previous response."); + builder.AddSequentialWorkflow( + "review-workflow", + [assistantBuilder, reviewerBuilder]) + .AddAsAIAgent(); + + if (builder.Environment.IsDevelopment()) + { + builder.AddDevUI(); + } + + var app = builder.Build(); + + if (builder.Environment.IsDevelopment()) + { + app.MapDevUI(); + } + + Console.WriteLine("DevUI is available at: https://localhost:50516/devui"); + Console.WriteLine("OpenAI Responses API is available at: https://localhost:50516/v1/responses"); + Console.WriteLine("Press Ctrl+C to stop the server."); + + app.Run(); + } +} diff --git a/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/README.md b/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/README.md new file mode 100644 index 0000000000..2b6cc28644 --- /dev/null +++ b/dotnet/samples/GettingStarted/DevUI/DevUI_Step01_BasicUsage/README.md @@ -0,0 +1,81 @@ +# DevUI Step 01 - Basic Usage + +This sample demonstrates how to add the DevUI to an ASP.NET Core application with AI agents. + +## What is DevUI? + +The DevUI provides an interactive web interface for testing and debugging AI agents during development. + +## Configuration + +Set the following environment variables: + +- `AZURE_OPENAI_ENDPOINT` - Your Azure OpenAI endpoint URL (required) +- `AZURE_OPENAI_DEPLOYMENT_NAME` - Your deployment name (defaults to "gpt-4o-mini") + +## Running the Sample + +1. Set your Azure OpenAI credentials as environment variables +2. Run the application: + ```bash + dotnet run + ``` +3. Open your browser to https://localhost:50516/devui +4. Select an agent or workflow from the dropdown and start chatting! + +## Sample Agents and Workflows + +This sample includes: + +**Agents:** +- **assistant** - A helpful assistant +- **poet** - A creative poet +- **coder** - An expert programmer + +**Workflows:** +- **review-workflow** - A sequential workflow that generates a response and then reviews it + +## Adding DevUI to Your Own Project + +To add DevUI to your ASP.NET Core application: + +1. Add the DevUI package and hosting packages: + ```bash + dotnet add package Microsoft.Agents.AI.DevUI + dotnet add package Microsoft.Agents.AI.Hosting + dotnet add package Microsoft.Agents.AI.Hosting.OpenAI + ``` + +2. Register your agents and workflows: + ```csharp + var builder = WebApplication.CreateBuilder(args); + + // Set up your chat client + builder.Services.AddChatClient(chatClient); + + // Register agents + builder.AddAIAgent("assistant", "You are a helpful assistant."); + + // Register workflows + var agent1Builder = builder.AddAIAgent("workflow-agent1", "You are agent 1."); + var agent2Builder = builder.AddAIAgent("workflow-agent2", "You are agent 2."); + builder.AddSequentialWorkflow("my-workflow", [agent1Builder, agent2Builder]) + .AddAsAIAgent(); + ``` + +3. Add DevUI services and map the endpoint: + ```csharp + builder.AddDevUI(); + var app = builder.Build(); + + app.MapDevUI(); + + // Add required endpoints + app.MapEntities(); + app.MapOpenAIResponses(); + app.MapOpenAIConversations(); + + app.Run(); + ``` + +4. Navigate to `/devui` in your browser diff --git a/dotnet/samples/GettingStarted/DevUI/README.md b/dotnet/samples/GettingStarted/DevUI/README.md new file mode 100644 index 0000000000..155d3f2b9d --- /dev/null +++ b/dotnet/samples/GettingStarted/DevUI/README.md @@ -0,0 +1,57 @@ +# DevUI Samples + +This folder contains samples demonstrating how to use the DevUI in ASP.NET Core applications. + +## What is DevUI? + +The DevUI provides an interactive web interface for testing and debugging AI agents during development. + +## Samples + +### [DevUI_Step01_BasicUsage](./DevUI_Step01_BasicUsage) + +Shows how to add DevUI to an ASP.NET Core application with multiple agents and workflows. + +**Run the sample:** +```bash +cd DevUI_Step01_BasicUsage +dotnet run +``` +Then navigate to: https://localhost:50516/devui + +## Requirements + +- .NET 8.0 or later +- ASP.NET Core +- Azure OpenAI credentials + +## Quick Start + +To add DevUI to your application: + +```csharp +var builder = WebApplication.CreateBuilder(args); + +// Set up the chat client +builder.Services.AddChatClient(chatClient); + +// Register your agents +builder.AddAIAgent("my-agent", "You are a helpful assistant."); + +// Add DevUI services +builder.AddDevUI(); + +var app = builder.Build(); + +// Map the DevUI endpoint +app.MapDevUI(); + +// Add required endpoints +app.MapEntities(); +app.MapOpenAIResponses(); +app.MapOpenAIConversations(); + +app.Run(); +``` + +Then navigate to `/devui` in your browser. diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/DevUIExtensions.cs b/dotnet/src/Microsoft.Agents.AI.DevUI/DevUIExtensions.cs new file mode 100644 index 0000000000..4a85de121a --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/DevUIExtensions.cs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.Agents.AI.DevUI; + +/// +/// Provides helper methods for configuring the Microsoft Agents AI DevUI in ASP.NET applications. +/// +public static class DevUIExtensions +{ + /// + /// Adds the necessary services for the DevUI to the application builder. + /// + public static IHostApplicationBuilder AddDevUI(this IHostApplicationBuilder builder) + { + ArgumentNullException.ThrowIfNull(builder); + builder.Services.AddOpenAIConversations(); + builder.Services.AddOpenAIResponses(); + + return builder; + } + + /// + /// Maps an endpoint that serves the DevUI from the '/devui' path. + /// + /// The to add the endpoint to. + /// A that can be used to add authorization or other endpoint configuration. + /// Thrown when is null. + public static IEndpointConventionBuilder MapDevUI( + this IEndpointRouteBuilder endpoints) + { + var group = endpoints.MapGroup(""); + group.MapDevUI(pattern: "/devui"); + group.MapEntities(); + group.MapOpenAIConversations(); + group.MapOpenAIResponses(); + return group; + } + + /// + /// Maps an endpoint that serves the DevUI. + /// + /// The to add the endpoint to. + /// + /// The route pattern for the endpoint (e.g., "/devui", "/agent-ui"). + /// Defaults to "/devui" if not specified. This is the path where DevUI will be accessible. + /// + /// A that can be used to add authorization or other endpoint configuration. + /// Thrown when is null. + /// Thrown when is null or whitespace. + internal static IEndpointConventionBuilder MapDevUI( + this IEndpointRouteBuilder endpoints, + [StringSyntax("Route")] string pattern = "/devui") + { + ArgumentNullException.ThrowIfNull(endpoints); + ArgumentException.ThrowIfNullOrWhiteSpace(pattern); + + // Ensure the pattern doesn't end with a slash for consistency + var cleanPattern = pattern.TrimEnd('/'); + + // Create the DevUI handler + var logger = endpoints.ServiceProvider.GetRequiredService>(); + var devUIHandler = new DevUIMiddleware(logger, cleanPattern); + + return endpoints.MapGet($"{cleanPattern}/{{*path}}", devUIHandler.HandleRequestAsync) + .WithName($"DevUI at {cleanPattern}") + .WithDescription("Interactive developer interface for Microsoft Agent Framework"); + } +} diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/DevUIMiddleware.cs b/dotnet/src/Microsoft.Agents.AI.DevUI/DevUIMiddleware.cs new file mode 100644 index 0000000000..fc6dd512ec --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/DevUIMiddleware.cs @@ -0,0 +1,236 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Collections.Frozen; +using System.IO.Compression; +using System.Reflection; +using System.Security.Cryptography; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.Primitives; +using Microsoft.Net.Http.Headers; + +namespace Microsoft.Agents.AI.DevUI; + +/// +/// Handler that serves embedded DevUI resource files from the 'resources' directory. +/// +internal sealed class DevUIMiddleware +{ + private const string GZipEncodingValue = "gzip"; + private static readonly StringValues s_gzipEncodingHeader = new(GZipEncodingValue); + private static readonly Assembly s_assembly = typeof(DevUIMiddleware).Assembly; + private static readonly FileExtensionContentTypeProvider s_contentTypeProvider = new(); + private static readonly StringValues s_cacheControl = new(new CacheControlHeaderValue() + { + NoCache = true, + NoStore = true, + }.ToString()); + + private readonly ILogger _logger; + private readonly FrozenDictionary _resourceCache; + private readonly string _basePath; + + /// + /// Initializes a new instance of the class. + /// + /// The logger instance. + /// The base path where DevUI is mounted. + public DevUIMiddleware(ILogger logger, string basePath) + { + ArgumentNullException.ThrowIfNull(logger); + ArgumentException.ThrowIfNullOrEmpty(basePath); + this._logger = logger; + this._basePath = basePath.TrimEnd('/'); + + // Build resource cache + var resourceNamePrefix = $"{s_assembly.GetName().Name}.resources."; + this._resourceCache = s_assembly + .GetManifestResourceNames() + .Where(p => p.StartsWith(resourceNamePrefix, StringComparison.Ordinal)) + .ToFrozenDictionary( + p => p[resourceNamePrefix.Length..].Replace('.', '/'), + CreateResourceEntry, + StringComparer.OrdinalIgnoreCase); + } + + /// + /// Handles an HTTP request for DevUI resources. + /// + /// The HTTP context. + public async Task HandleRequestAsync(HttpContext context) + { + var path = context.Request.Path.Value; + + if (path == null) + { + context.Response.StatusCode = StatusCodes.Status404NotFound; + return; + } + + // If requesting the base path without a trailing slash, redirect to include it + // This ensures relative URLs in the HTML work correctly + if (string.Equals(path, this._basePath, StringComparison.OrdinalIgnoreCase) && !path.EndsWith('/')) + { + var redirectUrl = $"{path}/"; + if (context.Request.QueryString.HasValue) + { + redirectUrl += context.Request.QueryString.Value; + } + + context.Response.StatusCode = StatusCodes.Status301MovedPermanently; + context.Response.Headers.Location = redirectUrl; + this._logger.LogDebug("Redirecting {OriginalPath} to {RedirectUrl}", path, redirectUrl); + return; + } + + // Remove the base path to get the resource path + var resourcePath = path.StartsWith(this._basePath, StringComparison.OrdinalIgnoreCase) + ? path.Substring(this._basePath.Length).TrimStart('/') + : path.TrimStart('/'); + + // If requesting the base path, serve index.html + if (string.IsNullOrEmpty(resourcePath)) + { + resourcePath = "index.html"; + } + + // Try to serve the embedded resource + if (await this.TryServeResourceAsync(context, resourcePath).ConfigureAwait(false)) + { + return; + } + + // If resource not found, try serving index.html for client-side routing + if (!resourcePath.Contains('.', StringComparison.Ordinal) || resourcePath.EndsWith('/')) + { + if (await this.TryServeResourceAsync(context, "index.html").ConfigureAwait(false)) + { + return; + } + } + + // Resource not found + context.Response.StatusCode = StatusCodes.Status404NotFound; + } + + private async Task TryServeResourceAsync(HttpContext context, string resourcePath) + { + try + { + if (!this._resourceCache.TryGetValue(resourcePath.Replace('.', '/'), out var cacheEntry)) + { + this._logger.LogDebug("Embedded resource not found: {ResourcePath}", resourcePath); + return false; + } + + var response = context.Response; + + // Check if client has cached version + if (context.Request.Headers.IfNoneMatch == cacheEntry.ETag) + { + response.StatusCode = StatusCodes.Status304NotModified; + this._logger.LogDebug("Resource not modified (304): {ResourcePath}", resourcePath); + return true; + } + + var responseHeaders = response.Headers; + + byte[] content; + bool serveCompressed; + if (cacheEntry.CompressedContent is not null && IsGZipAccepted(context.Request)) + { + serveCompressed = true; + responseHeaders.ContentEncoding = s_gzipEncodingHeader; + responseHeaders.ContentLength = cacheEntry.CompressedContent.Length; + content = cacheEntry.CompressedContent; + } + else + { + serveCompressed = false; + responseHeaders.ContentLength = cacheEntry.DecompressedContent!.Length; + content = cacheEntry.DecompressedContent; + } + + responseHeaders.CacheControl = s_cacheControl; + responseHeaders.ContentType = cacheEntry.ContentType; + responseHeaders.ETag = cacheEntry.ETag; + + await response.Body.WriteAsync(content, context.RequestAborted).ConfigureAwait(false); + + this._logger.LogDebug("Served embedded resource: {ResourcePath} (compressed: {Compressed})", resourcePath, serveCompressed); + return true; + } + catch (Exception ex) + { + this._logger.LogError(ex, "Error serving embedded resource: {ResourcePath}", resourcePath); + return false; + } + } + + private static bool IsGZipAccepted(HttpRequest httpRequest) + { + if (httpRequest.GetTypedHeaders().AcceptEncoding is not { Count: > 0 } acceptEncoding) + { + return false; + } + + for (int i = 0; i < acceptEncoding.Count; i++) + { + var encoding = acceptEncoding[i]; + + if (encoding.Quality is not 0 && + string.Equals(encoding.Value.Value, GZipEncodingValue, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + + private static ResourceEntry CreateResourceEntry(string resourceName) + { + using var resourceStream = s_assembly.GetManifestResourceStream(resourceName)!; + using var decompressedContent = new MemoryStream(); + + // Read and cache the original resource content + resourceStream.CopyTo(decompressedContent); + var decompressedArray = decompressedContent.ToArray(); + + // Compress the content + using var compressedContent = new MemoryStream(); + using (var gzip = new GZipStream(compressedContent, CompressionMode.Compress, leaveOpen: true)) + { + // This is a synchronous write to a memory stream. + // There is no benefit to asynchrony here. + gzip.Write(decompressedArray); + } + + // Only use compression if it actually reduces size + byte[]? compressedArray = compressedContent.Length < decompressedArray.Length + ? compressedContent.ToArray() + : null; + + var hash = SHA256.HashData(compressedArray ?? decompressedArray); + var eTag = $"\"{Convert.ToBase64String(hash)}\""; + + // Determine content type from resource name + var contentType = s_contentTypeProvider.TryGetContentType(resourceName, out var ct) + ? ct + : "application/octet-stream"; + + return new ResourceEntry(resourceName, decompressedArray, compressedArray, eTag, contentType); + } + + private sealed class ResourceEntry(string resourceName, byte[] decompressedContent, byte[]? compressedContent, string eTag, string contentType) + { + public byte[]? CompressedContent { get; } = compressedContent; + + public string ContentType { get; } = contentType; + + public byte[] DecompressedContent { get; } = decompressedContent; + + public string ETag { get; } = eTag; + + public string ResourceName { get; } = resourceName; + } +} diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/EntitiesJsonContext.cs b/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/EntitiesJsonContext.cs new file mode 100644 index 0000000000..fc8bbe3864 --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/EntitiesJsonContext.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.Agents.AI.DevUI.Entities; + +/// +/// JSON serialization context for entity-related types. +/// Enables AOT-compatible JSON serialization using source generators. +/// +[JsonSourceGenerationOptions( + JsonSerializerDefaults.Web, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +[JsonSerializable(typeof(EntityInfo))] +[JsonSerializable(typeof(DiscoveryResponse))] +[JsonSerializable(typeof(EnvVarRequirement))] +[JsonSerializable(typeof(List))] +[JsonSerializable(typeof(List))] +[JsonSerializable(typeof(Dictionary))] +[JsonSerializable(typeof(JsonElement))] +[ExcludeFromCodeCoverage] +internal sealed partial class EntitiesJsonContext : JsonSerializerContext; diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/EntityInfo.cs b/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/EntityInfo.cs new file mode 100644 index 0000000000..8b5e4e5492 --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/EntityInfo.cs @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.Agents.AI.DevUI.Entities; + +/// +/// Information about an environment variable required by an entity. +/// +internal sealed record EnvVarRequirement( + [property: JsonPropertyName("name")] + string Name, + + [property: JsonPropertyName("description")] + string? Description = null, + + [property: JsonPropertyName("required")] + bool Required = true, + + [property: JsonPropertyName("example")] + string? Example = null +); + +/// +/// Information about an entity (agent or workflow). +/// +internal sealed record EntityInfo( + [property: JsonPropertyName("id")] + string Id, + + [property: JsonPropertyName("type")] + string Type, + + [property: JsonPropertyName("name")] + string Name, + + [property: JsonPropertyName("description")] + string? Description = null, + + [property: JsonPropertyName("framework")] + string Framework = "dotnet", + + [property: JsonPropertyName("tools")] + List? Tools = null, + + [property: JsonPropertyName("metadata")] + Dictionary? Metadata = null +) +{ + [JsonPropertyName("source")] + public string? Source { get; init; } = "di"; + + [JsonPropertyName("original_url")] + public string? OriginalUrl { get; init; } + + // Workflow-specific fields + [JsonPropertyName("required_env_vars")] + public List? RequiredEnvVars { get; init; } + + [JsonPropertyName("executors")] + public List? Executors { get; init; } + + [JsonPropertyName("workflow_dump")] + public JsonElement? WorkflowDump { get; init; } + + [JsonPropertyName("input_schema")] + public JsonElement? InputSchema { get; init; } + + [JsonPropertyName("input_type_name")] + public string? InputTypeName { get; init; } + + [JsonPropertyName("start_executor_id")] + public string? StartExecutorId { get; init; } +}; + +/// +/// Response containing a list of discovered entities. +/// +internal sealed record DiscoveryResponse( + [property: JsonPropertyName("entities")] + List Entities +); diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/WorkflowSerializationExtensions.cs b/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/WorkflowSerializationExtensions.cs new file mode 100644 index 0000000000..81ce6182d1 --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/Entities/WorkflowSerializationExtensions.cs @@ -0,0 +1,193 @@ +// Copyright (c) Microsoft. All rights reserved. + +using Microsoft.Agents.AI.Workflows; +using Microsoft.Agents.AI.Workflows.Checkpointing; + +namespace Microsoft.Agents.AI.DevUI.Entities; + +/// +/// Extension methods for serializing workflows to DevUI-compatible format +/// +internal static class WorkflowSerializationExtensions +{ + // The frontend max iterations default value expected by the DevUI frontend + private const int MaxIterationsDefault = 100; + + /// + /// Converts a workflow to a dictionary representation compatible with DevUI frontend. + /// This matches the Python workflow.to_dict() format expected by the UI. + /// + public static Dictionary ToDevUIDict(this Workflow workflow) + { + var result = new Dictionary + { + ["id"] = workflow.Name ?? Guid.NewGuid().ToString(), + ["start_executor_id"] = workflow.StartExecutorId, + ["max_iterations"] = MaxIterationsDefault + }; + + // Add optional fields + if (!string.IsNullOrEmpty(workflow.Name)) + { + result["name"] = workflow.Name; + } + + if (!string.IsNullOrEmpty(workflow.Description)) + { + result["description"] = workflow.Description; + } + + // Convert executors to Python-compatible format + result["executors"] = ConvertExecutorsToDict(workflow); + + // Convert edges to edge_groups format + result["edge_groups"] = ConvertEdgesToEdgeGroups(workflow); + + return result; + } + + /// + /// Converts workflow executors to a dictionary format compatible with Python + /// + private static Dictionary ConvertExecutorsToDict(Workflow workflow) + { + var executors = new Dictionary(); + + // Extract executor IDs from edges and start executor + // (Registrations is internal, so we infer executors from the graph structure) + var executorIds = new HashSet { workflow.StartExecutorId }; + + var reflectedEdges = workflow.ReflectEdges(); + foreach (var (sourceId, edgeSet) in reflectedEdges) + { + executorIds.Add(sourceId); + foreach (var edge in edgeSet) + { + foreach (var sinkId in edge.Connection.SinkIds) + { + executorIds.Add(sinkId); + } + } + } + + // Create executor entries (we can't access internal Registrations for type info) + foreach (var executorId in executorIds) + { + executors[executorId] = new Dictionary + { + ["id"] = executorId, + ["type"] = "Executor" + }; + } + + return executors; + } + + /// + /// Converts workflow edges to edge_groups format expected by the UI + /// + private static List ConvertEdgesToEdgeGroups(Workflow workflow) + { + var edgeGroups = new List(); + var edgeGroupId = 0; + + // Get edges using the public ReflectEdges method + var reflectedEdges = workflow.ReflectEdges(); + + foreach (var (sourceId, edgeSet) in reflectedEdges) + { + foreach (var edgeInfo in edgeSet) + { + if (edgeInfo is DirectEdgeInfo directEdge) + { + // Single edge group for direct edges + var edges = new List(); + + foreach (var source in directEdge.Connection.SourceIds) + { + foreach (var sink in directEdge.Connection.SinkIds) + { + var edge = new Dictionary + { + ["source_id"] = source, + ["target_id"] = sink + }; + + // Add condition name if this is a conditional edge + if (directEdge.HasCondition) + { + edge["condition_name"] = "predicate"; + } + + edges.Add(edge); + } + } + + edgeGroups.Add(new Dictionary + { + ["id"] = $"edge_group_{edgeGroupId++}", + ["type"] = "SingleEdgeGroup", + ["edges"] = edges + }); + } + else if (edgeInfo is FanOutEdgeInfo fanOutEdge) + { + // FanOut edge group + var edges = new List(); + + foreach (var source in fanOutEdge.Connection.SourceIds) + { + foreach (var sink in fanOutEdge.Connection.SinkIds) + { + edges.Add(new Dictionary + { + ["source_id"] = source, + ["target_id"] = sink + }); + } + } + + var fanOutGroup = new Dictionary + { + ["id"] = $"edge_group_{edgeGroupId++}", + ["type"] = "FanOutEdgeGroup", + ["edges"] = edges + }; + + if (fanOutEdge.HasAssigner) + { + fanOutGroup["selection_func_name"] = "selector"; + } + + edgeGroups.Add(fanOutGroup); + } + else if (edgeInfo is FanInEdgeInfo fanInEdge) + { + // FanIn edge group + var edges = new List(); + + foreach (var source in fanInEdge.Connection.SourceIds) + { + foreach (var sink in fanInEdge.Connection.SinkIds) + { + edges.Add(new Dictionary + { + ["source_id"] = source, + ["target_id"] = sink + }); + } + } + + edgeGroups.Add(new Dictionary + { + ["id"] = $"edge_group_{edgeGroupId++}", + ["type"] = "FanInEdgeGroup", + ["edges"] = edges + }); + } + } + } + + return edgeGroups; + } +} diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/EntitiesApiExtensions.cs b/dotnet/src/Microsoft.Agents.AI.DevUI/EntitiesApiExtensions.cs new file mode 100644 index 0000000000..716dab8542 --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/EntitiesApiExtensions.cs @@ -0,0 +1,244 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Text.Json; + +using Microsoft.Agents.AI.DevUI.Entities; +using Microsoft.Agents.AI.Hosting; + +namespace Microsoft.Agents.AI.DevUI; + +/// +/// Provides extension methods for mapping entity discovery and management endpoints to an . +/// +internal static class EntitiesApiExtensions +{ + /// + /// Maps HTTP API endpoints for entity discovery and management. + /// + /// The to add the routes to. + /// The for method chaining. + /// + /// This extension method registers the following endpoints: + /// + /// GET /v1/entities - List all registered entities (agents and workflows) + /// GET /v1/entities/{entityId}/info - Get detailed information about a specific entity + /// + /// The endpoints are compatible with the Python DevUI frontend and automatically discover entities + /// from the registered and services. + /// + public static IEndpointConventionBuilder MapEntities(this IEndpointRouteBuilder endpoints) + { + var group = endpoints.MapGroup("/v1/entities") + .WithTags("Entities"); + + // List all entities + group.MapGet("", ListEntitiesAsync) + .WithName("ListEntities") + .WithSummary("List all registered entities (agents and workflows)") + .Produces(StatusCodes.Status200OK, contentType: "application/json"); + + // Get detailed entity information + group.MapGet("{entityId}/info", GetEntityInfoAsync) + .WithName("GetEntityInfo") + .WithSummary("Get detailed information about a specific entity") + .Produces(StatusCodes.Status200OK, contentType: "application/json") + .Produces(StatusCodes.Status404NotFound); + + return group; + } + + private static async Task ListEntitiesAsync( + AgentCatalog? agentCatalog, + WorkflowCatalog? workflowCatalog, + CancellationToken cancellationToken) + { + try + { + var entities = new List(); + + // Discover agents from the agent catalog + if (agentCatalog is not null) + { + await foreach (var agent in agentCatalog.GetAgentsAsync(cancellationToken).ConfigureAwait(false)) + { + if (agent.GetType().Name == "WorkflowHostAgent") + { + // HACK: ignore WorkflowHostAgent instances as they are just wrappers around workflows, + // and workflows are handled below. + continue; + } + + entities.Add(new EntityInfo( + Id: agent.Name ?? agent.Id, + Type: "agent", + Name: agent.Name ?? agent.Id, + Description: agent.Description, + Framework: "agent-framework", + Tools: null, + Metadata: [] + ) + { + Source = "in_memory" + }); + } + } + + // Discover workflows from the workflow catalog + if (workflowCatalog is not null) + { + await foreach (var workflow in workflowCatalog.GetWorkflowsAsync(cancellationToken).ConfigureAwait(false)) + { + // Extract executor IDs from the workflow structure + var executorIds = new HashSet { workflow.StartExecutorId }; + var reflectedEdges = workflow.ReflectEdges(); + foreach (var (sourceId, edgeSet) in reflectedEdges) + { + executorIds.Add(sourceId); + foreach (var edge in edgeSet) + { + foreach (var sinkId in edge.Connection.SinkIds) + { + executorIds.Add(sinkId); + } + } + } + + // Create a default input schema (string type) + var defaultInputSchema = new Dictionary + { + ["type"] = "string" + }; + + entities.Add(new EntityInfo( + Id: workflow.Name ?? workflow.StartExecutorId, + Type: "workflow", + Name: workflow.Name ?? workflow.StartExecutorId, + Description: workflow.Description, + Framework: "agent-framework", + Tools: [.. executorIds], + Metadata: [] + ) + { + Source = "in_memory", + WorkflowDump = JsonSerializer.SerializeToElement(workflow.ToDevUIDict()), + InputSchema = JsonSerializer.SerializeToElement(defaultInputSchema), + InputTypeName = "string", + StartExecutorId = workflow.StartExecutorId + }); + } + } + + return Results.Json(new DiscoveryResponse(entities), EntitiesJsonContext.Default.DiscoveryResponse); + } + catch (Exception ex) + { + return Results.Problem( + detail: ex.Message, + statusCode: StatusCodes.Status500InternalServerError, + title: "Error listing entities"); + } + } + + private static async Task GetEntityInfoAsync( + string entityId, + AgentCatalog? agentCatalog, + WorkflowCatalog? workflowCatalog, + CancellationToken cancellationToken) + { + try + { + // Try to find the entity among discovered agents + if (agentCatalog is not null) + { + await foreach (var agent in agentCatalog.GetAgentsAsync(cancellationToken).ConfigureAwait(false)) + { + if (agent.GetType().Name == "WorkflowHostAgent") + { + // HACK: ignore WorkflowHostAgent instances as they are just wrappers around workflows, + // and workflows are handled below. + continue; + } + + if (string.Equals(agent.Name, entityId, StringComparison.OrdinalIgnoreCase) || + string.Equals(agent.Id, entityId, StringComparison.OrdinalIgnoreCase)) + { + var entityInfo = new EntityInfo( + Id: agent.Name ?? agent.Id, + Type: "agent", + Name: agent.Name ?? agent.Id, + Description: agent.Description, + Framework: "agent-framework", + Tools: null, + Metadata: [] + ) + { + Source = "in_memory" + }; + + return Results.Json(entityInfo, EntitiesJsonContext.Default.EntityInfo); + } + } + } + + // Try to find the entity among discovered workflows + if (workflowCatalog is not null) + { + await foreach (var workflow in workflowCatalog.GetWorkflowsAsync(cancellationToken).ConfigureAwait(false)) + { + var workflowId = workflow.Name ?? workflow.StartExecutorId; + if (string.Equals(workflowId, entityId, StringComparison.OrdinalIgnoreCase)) + { + // Extract executor IDs from the workflow structure + var executorIds = new HashSet { workflow.StartExecutorId }; + var reflectedEdges = workflow.ReflectEdges(); + foreach (var (sourceId, edgeSet) in reflectedEdges) + { + executorIds.Add(sourceId); + foreach (var edge in edgeSet) + { + foreach (var sinkId in edge.Connection.SinkIds) + { + executorIds.Add(sinkId); + } + } + } + + // Create a default input schema (string type) + var defaultInputSchema = new Dictionary + { + ["type"] = "string" + }; + + var entityInfo = new EntityInfo( + Id: workflowId, + Type: "workflow", + Name: workflow.Name ?? workflow.StartExecutorId, + Description: workflow.Description, + Framework: "agent-framework", + Tools: [.. executorIds], + Metadata: [] + ) + { + Source = "in_memory", + WorkflowDump = JsonSerializer.SerializeToElement(workflow.ToDevUIDict()), + InputSchema = JsonSerializer.SerializeToElement(defaultInputSchema), + InputTypeName = "Input", + StartExecutorId = workflow.StartExecutorId + }; + + return Results.Json(entityInfo, EntitiesJsonContext.Default.EntityInfo); + } + } + } + + return Results.NotFound(new { error = new { message = $"Entity '{entityId}' not found.", type = "invalid_request_error" } }); + } + catch (Exception ex) + { + return Results.Problem( + detail: ex.Message, + statusCode: StatusCodes.Status500InternalServerError, + title: "Error getting entity info"); + } + } +} diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/Microsoft.Agents.AI.DevUI.Frontend.targets b/dotnet/src/Microsoft.Agents.AI.DevUI/Microsoft.Agents.AI.DevUI.Frontend.targets new file mode 100644 index 0000000000..f62a92e28d --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/Microsoft.Agents.AI.DevUI.Frontend.targets @@ -0,0 +1,68 @@ + + + + + $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..\..\..\python\packages\devui\frontend')) + $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..\..\..\python\packages\devui\agent_framework_devui\ui')) + $(FrontendRoot)\package.json + $(FrontendRoot)\node_modules + + + + + + + + + + + + + + + + + + + + + + + + $(BaseIntermediateOutputPath)\frontend.build.marker + + + + + + + + + + + + + + resources\$([MSBuild]::MakeRelative('$(FrontendBuildOutput)', '%(Identity)')) + + + + + + + + + + + + + + + + + + + + + + diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/Microsoft.Agents.AI.DevUI.csproj b/dotnet/src/Microsoft.Agents.AI.DevUI/Microsoft.Agents.AI.DevUI.csproj new file mode 100644 index 0000000000..43f5b54eac --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/Microsoft.Agents.AI.DevUI.csproj @@ -0,0 +1,31 @@ + + + + net9.0 + enable + enable + Microsoft.Agents.AI.DevUI + Library + Microsoft Agent Framework Developer UI + Provides Microsoft Agent Framework support for developer UI. + true + + $(NoWarn);CS1591;CA1852;CA1050;RCS1037;RCS1036;RCS1124;RCS1021;RCS1146;RCS1211;CA2007;CA1308;IL2026;IL3050;CA1812 + + + + + + + + + + + + + + + + + + diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/Properties/launchSettings.json b/dotnet/src/Microsoft.Agents.AI.DevUI/Properties/launchSettings.json new file mode 100644 index 0000000000..32587da80b --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "Microsoft.Agents.AI.DevUI": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:57966;http://localhost:57967" + } + } +} \ No newline at end of file diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/README.md b/dotnet/src/Microsoft.Agents.AI.DevUI/README.md new file mode 100644 index 0000000000..1f106e29ef --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/README.md @@ -0,0 +1,42 @@ +# Microsoft.Agents.AI.DevUI + +This package provides a web interface for testing and debugging AI agents during development. + +## Installation + +```bash +dotnet add package Microsoft.Agents.AI.DevUI +dotnet add package Microsoft.Agents.AI.Hosting +dotnet add package Microsoft.Agents.AI.Hosting.OpenAI +``` + +## Usage + +Add DevUI services and map the endpoint in your ASP.NET Core application: + +```csharp +using Microsoft.Agents.AI.DevUI; +using Microsoft.Agents.AI.Hosting; +using Microsoft.Agents.AI.Hosting.OpenAI; + +var builder = WebApplication.CreateBuilder(args); + +// Register your agents +builder.AddAIAgent("assistant", "You are a helpful assistant."); + +if (builder.Environment.IsDevelopment()) +{ + // Add DevUI services + builder.AddDevUI(); +} + +var app = builder.Build(); + +if (builder.Environment.IsDevelopment()) +{ + // Map DevUI endpoint to /devui + app.MapDevUI(); +} + +app.Run(); +``` diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/wwwroot/index.html b/dotnet/src/Microsoft.Agents.AI.DevUI/wwwroot/index.html new file mode 100644 index 0000000000..ff0ead674e --- /dev/null +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/wwwroot/index.html @@ -0,0 +1,14 @@ + + + + + + + Agent Framework Dev UI + + + + +
+ + diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowThread.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowThread.cs index 7866df5ec6..ffa044791f 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowThread.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowThread.cs @@ -153,13 +153,27 @@ IAsyncEnumerable InvokeStageAsync( case AgentRunUpdateEvent agentUpdate: yield return agentUpdate.Update; break; + case RequestInfoEvent requestInfo: FunctionCallContent fcContent = requestInfo.Request.ToFunctionCall(); AgentRunResponseUpdate update = this.CreateUpdate(this.LastResponseId, fcContent); yield return update; break; + case SuperStepCompletedEvent stepCompleted: this.LastCheckpoint = stepCompleted.CompletionInfo?.Checkpoint; + goto default; + + default: + // Emit all other workflow events for observability (DevUI, logging, etc.) + yield return new AgentRunResponseUpdate(ChatRole.Assistant, []) + { + CreatedAt = DateTimeOffset.UtcNow, + MessageId = Guid.NewGuid().ToString("N"), + Role = ChatRole.Assistant, + ResponseId = this.LastResponseId, + RawRepresentation = evt + }; break; } } diff --git a/python/packages/devui/agent_framework_devui/ui/assets/index-CE4pGoXh.css b/python/packages/devui/agent_framework_devui/ui/assets/index-CE4pGoXh.css deleted file mode 100644 index c86e173c41..0000000000 --- a/python/packages/devui/agent_framework_devui/ui/assets/index-CE4pGoXh.css +++ /dev/null @@ -1 +0,0 @@ -/*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-orange-50:oklch(98% .016 73.684);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-800:oklch(47% .157 37.304);--color-orange-900:oklch(40.8% .123 38.172);--color-orange-950:oklch(26.6% .079 36.259);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-green-50:oklch(98.2% .018 155.826);--color-green-100:oklch(96.2% .044 156.743);--color-green-200:oklch(92.5% .084 155.995);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-green-900:oklch(39.3% .095 152.535);--color-green-950:oklch(26.6% .065 152.934);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-emerald-800:oklch(43.2% .095 166.913);--color-emerald-900:oklch(37.8% .077 168.94);--color-emerald-950:oklch(26.2% .051 172.552);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-blue-950:oklch(28.2% .091 267.935);--color-purple-50:oklch(97.7% .014 308.299);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-900:oklch(38.1% .176 304.987);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-widest:.1em;--leading-tight:1.25;--leading-relaxed:1.625;--drop-shadow-lg:0 4px 4px #00000026;--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--animate-bounce:bounce 1s infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){*{outline-color:color-mix(in oklab,var(--ring)50%,transparent)}}body{background-color:var(--background);color:var(--foreground)}}@layer components;@layer utilities{.\@container\/card-header{container:card-header/inline-size}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing)*0)}.inset-2{inset:calc(var(--spacing)*2)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.-top-1{top:calc(var(--spacing)*-1)}.-top-2{top:calc(var(--spacing)*-2)}.top-1{top:calc(var(--spacing)*1)}.top-2{top:calc(var(--spacing)*2)}.top-4{top:calc(var(--spacing)*4)}.-right-1{right:calc(var(--spacing)*-1)}.-right-2{right:calc(var(--spacing)*-2)}.right-0{right:calc(var(--spacing)*0)}.right-1{right:calc(var(--spacing)*1)}.right-2{right:calc(var(--spacing)*2)}.right-3{right:calc(var(--spacing)*3)}.right-4{right:calc(var(--spacing)*4)}.-bottom-2{bottom:calc(var(--spacing)*-2)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-3{bottom:calc(var(--spacing)*3)}.bottom-14{bottom:calc(var(--spacing)*14)}.bottom-24{bottom:calc(var(--spacing)*24)}.-left-2{left:calc(var(--spacing)*-2)}.left-0{left:calc(var(--spacing)*0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.container\!{width:100%!important}@media (min-width:40rem){.container\!{max-width:40rem!important}}@media (min-width:48rem){.container\!{max-width:48rem!important}}@media (min-width:64rem){.container\!{max-width:64rem!important}}@media (min-width:80rem){.container\!{max-width:80rem!important}}@media (min-width:96rem){.container\!{max-width:96rem!important}}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.my-3{margin-block:calc(var(--spacing)*3)}.my-4{margin-block:calc(var(--spacing)*4)}.mt-0{margin-top:calc(var(--spacing)*0)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-12{margin-top:calc(var(--spacing)*12)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-1\.5{margin-right:calc(var(--spacing)*1.5)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-5{margin-left:calc(var(--spacing)*5)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.field-sizing-content{field-sizing:content}.size-2{width:calc(var(--spacing)*2);height:calc(var(--spacing)*2)}.size-3\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-9{width:calc(var(--spacing)*9);height:calc(var(--spacing)*9)}.\!h-2{height:calc(var(--spacing)*2)!important}.h-0{height:calc(var(--spacing)*0)}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-12{height:calc(var(--spacing)*12)}.h-14{height:calc(var(--spacing)*14)}.h-16{height:calc(var(--spacing)*16)}.h-32{height:calc(var(--spacing)*32)}.h-96{height:calc(var(--spacing)*96)}.h-\[1\.2rem\]{height:1.2rem}.h-\[500px\]{height:500px}.h-\[calc\(100vh-3\.5rem\)\]{height:calc(100vh - 3.5rem)}.h-\[calc\(100vh-3\.7rem\)\]{height:calc(100vh - 3.7rem)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\(--radix-dropdown-menu-content-available-height\){max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-\(--radix-select-content-available-height\){max-height:var(--radix-select-content-available-height)}.max-h-20{max-height:calc(var(--spacing)*20)}.max-h-24{max-height:calc(var(--spacing)*24)}.max-h-32{max-height:calc(var(--spacing)*32)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-\[90vh\]{max-height:90vh}.max-h-\[200px\]{max-height:200px}.max-h-none{max-height:none}.max-h-screen{max-height:100vh}.\!min-h-0{min-height:calc(var(--spacing)*0)!important}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-16{min-height:calc(var(--spacing)*16)}.min-h-\[36px\]{min-height:36px}.min-h-\[40px\]{min-height:40px}.min-h-\[50vh\]{min-height:50vh}.min-h-\[240px\]{min-height:240px}.min-h-\[400px\]{min-height:400px}.min-h-screen{min-height:100vh}.\!w-2{width:calc(var(--spacing)*2)!important}.w-1{width:calc(var(--spacing)*1)}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-10{width:calc(var(--spacing)*10)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-56{width:calc(var(--spacing)*56)}.w-64{width:calc(var(--spacing)*64)}.w-80{width:calc(var(--spacing)*80)}.w-\[1\.2rem\]{width:1.2rem}.w-\[600px\]{width:600px}.w-\[800px\]{width:800px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[80\%\]{max-width:80%}.max-w-\[90vw\]{max-width:90vw}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.\!min-w-0{min-width:calc(var(--spacing)*0)!important}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[300px\]{min-width:300px}.min-w-\[400px\]{min-width:400px}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-\(--radix-dropdown-menu-content-transform-origin\){transform-origin:var(--radix-dropdown-menu-content-transform-origin)}.origin-\(--radix-select-content-transform-origin\){transform-origin:var(--radix-select-content-transform-origin)}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-4{--tw-translate-x:calc(var(--spacing)*4);translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-75{--tw-scale-x:75%;--tw-scale-y:75%;--tw-scale-z:75%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.rotate-0{rotate:none}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-bounce{animation:var(--animate-bounce)}.animate-in{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-row-resize{cursor:row-resize}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.scroll-my-1{scroll-margin-block:calc(var(--spacing)*1)}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.auto-rows-min{grid-auto-rows:min-content}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-rows-\[auto_auto\]{grid-template-rows:auto auto}.flex-col{flex-direction:column}.flex-row-reverse{flex-direction:row-reverse}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-1>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*1)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.self-start{align-self:flex-start}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.\!rounded-full{border-radius:3.40282e38px!important}.rounded{border-radius:.25rem}.rounded-\[4px\]{border-radius:4px}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-none{border-radius:0}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.\!border{border-style:var(--tw-border-style)!important;border-width:1px!important}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-0{border-left-style:var(--tw-border-style);border-left-width:0}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.\!border-gray-600{border-color:var(--color-gray-600)!important}.border-\[\#643FB2\]{border-color:#643fb2}.border-\[\#643FB2\]\/30{border-color:#643fb24d}.border-\[\#643FB2\]\/40{border-color:#643fb266}.border-amber-200{border-color:var(--color-amber-200)}.border-blue-200{border-color:var(--color-blue-200)}.border-blue-300{border-color:var(--color-blue-300)}.border-blue-400{border-color:var(--color-blue-400)}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/30{border-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.border-blue-500\/40{border-color:#3080ff66}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/40{border-color:color-mix(in oklab,var(--color-blue-500)40%,transparent)}}.border-border,.border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab,red,red)){.border-border\/50{border-color:color-mix(in oklab,var(--border)50%,transparent)}}.border-current\/30{border-color:currentColor}@supports (color:color-mix(in lab,red,red)){.border-current\/30{border-color:color-mix(in oklab,currentcolor 30%,transparent)}}.border-destructive\/30{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/30{border-color:color-mix(in oklab,var(--destructive)30%,transparent)}}.border-destructive\/50{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/50{border-color:color-mix(in oklab,var(--destructive)50%,transparent)}}.border-destructive\/70{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/70{border-color:color-mix(in oklab,var(--destructive)70%,transparent)}}.border-emerald-300{border-color:var(--color-emerald-300)}.border-foreground\/5{border-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.border-foreground\/5{border-color:color-mix(in oklab,var(--foreground)5%,transparent)}}.border-foreground\/10{border-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.border-foreground\/10{border-color:color-mix(in oklab,var(--foreground)10%,transparent)}}.border-foreground\/20{border-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.border-foreground\/20{border-color:color-mix(in oklab,var(--foreground)20%,transparent)}}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-green-200{border-color:var(--color-green-200)}.border-green-500{border-color:var(--color-green-500)}.border-green-500\/30{border-color:#00c7584d}@supports (color:color-mix(in lab,red,red)){.border-green-500\/30{border-color:color-mix(in oklab,var(--color-green-500)30%,transparent)}}.border-green-500\/40{border-color:#00c75866}@supports (color:color-mix(in lab,red,red)){.border-green-500\/40{border-color:color-mix(in oklab,var(--color-green-500)40%,transparent)}}.border-input{border-color:var(--input)}.border-muted{border-color:var(--muted)}.border-orange-200{border-color:var(--color-orange-200)}.border-orange-500{border-color:var(--color-orange-500)}.border-primary,.border-primary\/20{border-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.border-primary\/20{border-color:color-mix(in oklab,var(--primary)20%,transparent)}}.border-red-200{border-color:var(--color-red-200)}.border-red-500{border-color:var(--color-red-500)}.border-transparent{border-color:#0000}.border-yellow-200{border-color:var(--color-yellow-200)}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.bg-\[\#643FB2\]{background-color:#643fb2}.bg-\[\#643FB2\]\/5{background-color:#643fb20d}.bg-\[\#643FB2\]\/10{background-color:#643fb21a}.bg-accent\/10{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-accent\/10{background-color:color-mix(in oklab,var(--accent)10%,transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-background{background-color:var(--background)}.bg-black{background-color:var(--color-black)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-50\/80{background-color:#eff6ffcc}@supports (color:color-mix(in lab,red,red)){.bg-blue-50\/80{background-color:color-mix(in oklab,var(--color-blue-50)80%,transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\/5{background-color:#3080ff0d}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/5{background-color:color-mix(in oklab,var(--color-blue-500)5%,transparent)}}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/10{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-current{background-color:currentColor}.bg-destructive,.bg-destructive\/5{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.bg-destructive\/5{background-color:color-mix(in oklab,var(--destructive)5%,transparent)}}.bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.bg-destructive\/10{background-color:color-mix(in oklab,var(--destructive)10%,transparent)}}.bg-destructive\/80{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.bg-destructive\/80{background-color:color-mix(in oklab,var(--destructive)80%,transparent)}}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-foreground\/5{background-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.bg-foreground\/5{background-color:color-mix(in oklab,var(--foreground)5%,transparent)}}.bg-foreground\/10{background-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.bg-foreground\/10{background-color:color-mix(in oklab,var(--foreground)10%,transparent)}}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-900\/90{background-color:#101828e6}@supports (color:color-mix(in lab,red,red)){.bg-gray-900\/90{background-color:color-mix(in oklab,var(--color-gray-900)90%,transparent)}}.bg-green-50{background-color:var(--color-green-50)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\/5{background-color:#00c7580d}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/5{background-color:color-mix(in oklab,var(--color-green-500)5%,transparent)}}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/10{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.bg-muted,.bg-muted\/30{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/30{background-color:color-mix(in oklab,var(--muted)30%,transparent)}}.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/50{background-color:color-mix(in oklab,var(--muted)50%,transparent)}}.bg-orange-50{background-color:var(--color-orange-50)}.bg-orange-100{background-color:var(--color-orange-100)}.bg-orange-500{background-color:var(--color-orange-500)}.bg-popover{background-color:var(--popover)}.bg-primary,.bg-primary\/10{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.bg-primary\/10{background-color:color-mix(in oklab,var(--primary)10%,transparent)}}.bg-primary\/30{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.bg-primary\/30{background-color:color-mix(in oklab,var(--primary)30%,transparent)}}.bg-primary\/40{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.bg-primary\/40{background-color:color-mix(in oklab,var(--primary)40%,transparent)}}.bg-purple-50{background-color:var(--color-purple-50)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-white\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-100{background-color:var(--color-yellow-100)}.fill-current{fill:currentColor}.object-cover{object-fit:cover}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-\[1px\]{padding:1px}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-8{padding-top:calc(var(--spacing)*8)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-8{padding-right:calc(var(--spacing)*8)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pb-6{padding-bottom:calc(var(--spacing)*6)}.pb-12{padding-bottom:calc(var(--spacing)*12)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-3{padding-left:calc(var(--spacing)*3)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-8{padding-left:calc(var(--spacing)*8)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#643FB2\]{color:#643fb2}.text-amber-500{color:var(--color-amber-500)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-card-foreground{color:var(--card-foreground)}.text-current{color:currentColor}.text-destructive{color:var(--destructive)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-emerald-800{color:var(--color-emerald-800)}.text-foreground{color:var(--foreground)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-green-500{color:var(--color-green-500)}.text-green-600{color:var(--color-green-600)}.text-green-700{color:var(--color-green-700)}.text-green-800{color:var(--color-green-800)}.text-muted-foreground,.text-muted-foreground\/80{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/80{color:color-mix(in oklab,var(--muted-foreground)80%,transparent)}}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-800{color:var(--color-orange-800)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-purple-500{color:var(--color-purple-500)}.text-purple-600{color:var(--color-purple-600)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-red-800{color:var(--color-red-800)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-white{color:var(--color-white)}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[\#643FB2\]\/20{--tw-shadow-color:#643fb233}@supports (color:color-mix(in lab,red,red)){.shadow-\[\#643FB2\]\/20{--tw-shadow-color:color-mix(in oklab,oklab(47.4316% .069152 -.159147/.2) var(--tw-shadow-alpha),transparent)}}.shadow-green-500\/20{--tw-shadow-color:#00c75833}@supports (color:color-mix(in lab,red,red)){.shadow-green-500\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-green-500)20%,transparent)var(--tw-shadow-alpha),transparent)}}.shadow-orange-500\/20{--tw-shadow-color:#fe6e0033}@supports (color:color-mix(in lab,red,red)){.shadow-orange-500\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-orange-500)20%,transparent)var(--tw-shadow-alpha),transparent)}}.shadow-primary\/25{--tw-shadow-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.shadow-primary\/25{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--primary)25%,transparent)var(--tw-shadow-alpha),transparent)}}.shadow-red-500\/20{--tw-shadow-color:#fb2c3633}@supports (color:color-mix(in lab,red,red)){.shadow-red-500\/20{--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--color-red-500)20%,transparent)var(--tw-shadow-alpha),transparent)}}.ring-blue-500{--tw-ring-color:var(--color-blue-500)}.ring-offset-2{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.drop-shadow-lg{--tw-drop-shadow-size:drop-shadow(0 4px 4px var(--tw-drop-shadow-color,#00000026));--tw-drop-shadow:drop-shadow(var(--drop-shadow-lg));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,visibility,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-none{transition-property:none}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[animation-delay\:-0\.3s\]{animation-delay:-.3s}.\[animation-delay\:-0\.15s\]{animation-delay:-.15s}.fade-in{--tw-enter-opacity:0}.running{animation-play-state:running}.slide-in-from-bottom-2{--tw-enter-translate-y:calc(2*var(--spacing))}.group-open\:rotate-180:is(:where(.group):is([open],:popover-open,:open) *){rotate:180deg}@media (hover:hover){.group-hover\:bg-primary:is(:where(.group):hover *){background-color:var(--primary)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\:shadow-md:is(:where(.group):hover *){--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.group-hover\:shadow-primary\/20:is(:where(.group):hover *){--tw-shadow-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.group-hover\:shadow-primary\/20:is(:where(.group):hover *){--tw-shadow-color:color-mix(in oklab,color-mix(in oklab,var(--primary)20%,transparent)var(--tw-shadow-alpha),transparent)}}}.group-data-\[disabled\=true\]\:pointer-events-none:is(:where(.group)[data-disabled=true] *){pointer-events:none}.group-data-\[disabled\=true\]\:opacity-50:is(:where(.group)[data-disabled=true] *){opacity:.5}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-50:is(:where(.peer):disabled~*){opacity:.5}.selection\:bg-primary ::selection{background-color:var(--primary)}.selection\:bg-primary::selection{background-color:var(--primary)}.selection\:text-primary-foreground ::selection{color:var(--primary-foreground)}.selection\:text-primary-foreground::selection{color:var(--primary-foreground)}.file\:inline-flex::file-selector-button{display:inline-flex}.file\:h-7::file-selector-button{height:calc(var(--spacing)*7)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.first\:mt-0:first-child{margin-top:calc(var(--spacing)*0)}.last\:border-r-0:last-child{border-right-style:var(--tw-border-style);border-right-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:bg-\[\#643FB2\]\/10:hover{background-color:#643fb21a}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-amber-100:hover{background-color:var(--color-amber-100)}.hover\:bg-blue-500\/10:hover{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-blue-500\/10:hover{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.hover\:bg-destructive\/20:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/20:hover{background-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.hover\:bg-destructive\/80:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/80:hover{background-color:color-mix(in oklab,var(--destructive)80%,transparent)}}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive)90%,transparent)}}.hover\:bg-green-500\/10:hover{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-green-500\/10:hover{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.hover\:bg-muted:hover,.hover\:bg-muted\/30:hover{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-muted\/30:hover{background-color:color-mix(in oklab,var(--muted)30%,transparent)}}.hover\:bg-muted\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted)50%,transparent)}}.hover\:bg-primary\/20:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/20:hover{background-color:color-mix(in oklab,var(--primary)20%,transparent)}}.hover\:bg-primary\/80:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/80:hover{background-color:color-mix(in oklab,var(--primary)80%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary)90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary)80%,transparent)}}.hover\:bg-white:hover{background-color:var(--color-white)}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(3px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.focus-visible\:ring-ring:focus-visible,.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab,var(--ring)50%,transparent)}}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.has-data-\[slot\=card-action\]\:grid-cols-\[1fr_auto\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-\[\>svg\]\:px-2\.5:has(>svg){padding-inline:calc(var(--spacing)*2.5)}.has-\[\>svg\]\:px-3:has(>svg){padding-inline:calc(var(--spacing)*3)}.has-\[\>svg\]\:px-4:has(>svg){padding-inline:calc(var(--spacing)*4)}.aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[inset\]\:pl-8[data-inset]{padding-left:calc(var(--spacing)*8)}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:var(--muted-foreground)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:calc(2*var(--spacing))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:calc(2*var(--spacing))}.data-\[size\=default\]\:h-9[data-size=default]{height:calc(var(--spacing)*9)}.data-\[size\=sm\]\:h-8[data-size=sm]{height:calc(var(--spacing)*8)}:is(.\*\:data-\[slot\=select-value\]\:line-clamp-1>*)[data-slot=select-value]{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}:is(.\*\:data-\[slot\=select-value\]\:flex>*)[data-slot=select-value]{display:flex}:is(.\*\:data-\[slot\=select-value\]\:items-center>*)[data-slot=select-value]{align-items:center}:is(.\*\:data-\[slot\=select-value\]\:gap-2>*)[data-slot=select-value]{gap:calc(var(--spacing)*2)}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.data-\[state\=checked\]\:border-primary[data-state=checked]{border-color:var(--primary)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--primary)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--primary-foreground)}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=open\]\:animate-in[data-state=open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\[state\=open\]\:text-accent-foreground[data-state=open]{color:var(--accent-foreground)}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[variant\=destructive\]\:text-destructive[data-variant=destructive]{color:var(--destructive)}.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:color-mix(in oklab,var(--destructive)10%,transparent)}}.data-\[variant\=destructive\]\:focus\:text-destructive[data-variant=destructive]:focus{color:var(--destructive)}@media (min-width:40rem){.sm\:col-span-2{grid-column:span 2/span 2}.sm\:w-64{width:calc(var(--spacing)*64)}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:flex-none{flex:none}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}}@media (min-width:48rem){.md\:col-span-2{grid-column:span 2/span 2}.md\:col-start-2{grid-column-start:2}.md\:inline{display:inline}.md\:max-w-2xl{max-width:var(--container-2xl)}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:gap-8{gap:calc(var(--spacing)*8)}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (min-width:64rem){.lg\:col-span-3{grid-column:span 3/span 3}.lg\:max-w-4xl{max-width:var(--container-4xl)}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}}@media (min-width:80rem){.xl\:col-span-2{grid-column:span 2/span 2}.xl\:col-span-4{grid-column:span 4/span 4}.xl\:max-w-5xl{max-width:var(--container-5xl)}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.dark\:scale-0:is(.dark *){--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x)var(--tw-scale-y)}.dark\:scale-100:is(.dark *){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.dark\:-rotate-90:is(.dark *){rotate:-90deg}.dark\:rotate-0:is(.dark *){rotate:none}.dark\:\!border-gray-500:is(.dark *){border-color:var(--color-gray-500)!important}.dark\:\!border-gray-600:is(.dark *){border-color:var(--color-gray-600)!important}.dark\:border-\[\#8B5CF6\]:is(.dark *){border-color:#8b5cf6}.dark\:border-\[\#8B5CF6\]\/30:is(.dark *){border-color:#8b5cf64d}.dark\:border-\[\#8B5CF6\]\/40:is(.dark *){border-color:#8b5cf666}.dark\:border-amber-800:is(.dark *){border-color:var(--color-amber-800)}.dark\:border-amber-900:is(.dark *){border-color:var(--color-amber-900)}.dark\:border-blue-500:is(.dark *){border-color:var(--color-blue-500)}.dark\:border-blue-500\/30:is(.dark *){border-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.dark\:border-blue-500\/30:is(.dark *){border-color:color-mix(in oklab,var(--color-blue-500)30%,transparent)}}.dark\:border-blue-500\/40:is(.dark *){border-color:#3080ff66}@supports (color:color-mix(in lab,red,red)){.dark\:border-blue-500\/40:is(.dark *){border-color:color-mix(in oklab,var(--color-blue-500)40%,transparent)}}.dark\:border-blue-600:is(.dark *){border-color:var(--color-blue-600)}.dark\:border-blue-800:is(.dark *){border-color:var(--color-blue-800)}.dark\:border-emerald-600:is(.dark *){border-color:var(--color-emerald-600)}.dark\:border-gray-600:is(.dark *){border-color:var(--color-gray-600)}.dark\:border-gray-700:is(.dark *){border-color:var(--color-gray-700)}.dark\:border-green-400:is(.dark *){border-color:var(--color-green-400)}.dark\:border-green-400\/30:is(.dark *){border-color:#05df724d}@supports (color:color-mix(in lab,red,red)){.dark\:border-green-400\/30:is(.dark *){border-color:color-mix(in oklab,var(--color-green-400)30%,transparent)}}.dark\:border-green-400\/40:is(.dark *){border-color:#05df7266}@supports (color:color-mix(in lab,red,red)){.dark\:border-green-400\/40:is(.dark *){border-color:color-mix(in oklab,var(--color-green-400)40%,transparent)}}.dark\:border-green-800:is(.dark *){border-color:var(--color-green-800)}.dark\:border-input:is(.dark *){border-color:var(--input)}.dark\:border-orange-400:is(.dark *){border-color:var(--color-orange-400)}.dark\:border-orange-800:is(.dark *){border-color:var(--color-orange-800)}.dark\:border-red-400:is(.dark *){border-color:var(--color-red-400)}.dark\:border-red-800:is(.dark *){border-color:var(--color-red-800)}.dark\:\!bg-gray-800\/90:is(.dark *){background-color:#1e2939e6!important}@supports (color:color-mix(in lab,red,red)){.dark\:\!bg-gray-800\/90:is(.dark *){background-color:color-mix(in oklab,var(--color-gray-800)90%,transparent)!important}}.dark\:bg-\[\#8B5CF6\]:is(.dark *){background-color:#8b5cf6}.dark\:bg-\[\#8B5CF6\]\/5:is(.dark *){background-color:#8b5cf60d}.dark\:bg-\[\#8B5CF6\]\/10:is(.dark *){background-color:#8b5cf61a}.dark\:bg-amber-950\/20:is(.dark *){background-color:#46190133}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-950\/20:is(.dark *){background-color:color-mix(in oklab,var(--color-amber-950)20%,transparent)}}.dark\:bg-amber-950\/50:is(.dark *){background-color:#46190180}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-950\/50:is(.dark *){background-color:color-mix(in oklab,var(--color-amber-950)50%,transparent)}}.dark\:bg-background:is(.dark *){background-color:var(--background)}.dark\:bg-blue-500\/5:is(.dark *){background-color:#3080ff0d}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/5:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-500)5%,transparent)}}.dark\:bg-blue-500\/10:is(.dark *){background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-500\/10:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.dark\:bg-blue-900:is(.dark *){background-color:var(--color-blue-900)}.dark\:bg-blue-900\/50:is(.dark *){background-color:#1c398e80}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-900\/50:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-900)50%,transparent)}}.dark\:bg-blue-950\/20:is(.dark *){background-color:#16245633}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-950\/20:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-950)20%,transparent)}}.dark\:bg-blue-950\/40:is(.dark *){background-color:#16245666}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-950\/40:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-950)40%,transparent)}}.dark\:bg-blue-950\/50:is(.dark *){background-color:#16245680}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-950\/50:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-950)50%,transparent)}}.dark\:bg-card:is(.dark *){background-color:var(--card)}.dark\:bg-destructive\/20:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-destructive\/20:is(.dark *){background-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.dark\:bg-destructive\/60:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-destructive\/60:is(.dark *){background-color:color-mix(in oklab,var(--destructive)60%,transparent)}}.dark\:bg-emerald-900\/50:is(.dark *){background-color:#004e3b80}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-900\/50:is(.dark *){background-color:color-mix(in oklab,var(--color-emerald-900)50%,transparent)}}.dark\:bg-emerald-950\/50:is(.dark *){background-color:#002c2280}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-950\/50:is(.dark *){background-color:color-mix(in oklab,var(--color-emerald-950)50%,transparent)}}.dark\:bg-foreground\/10:is(.dark *){background-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-foreground\/10:is(.dark *){background-color:color-mix(in oklab,var(--foreground)10%,transparent)}}.dark\:bg-gray-500:is(.dark *){background-color:var(--color-gray-500)}.dark\:bg-gray-800:is(.dark *){background-color:var(--color-gray-800)}.dark\:bg-gray-800\/90:is(.dark *){background-color:#1e2939e6}@supports (color:color-mix(in lab,red,red)){.dark\:bg-gray-800\/90:is(.dark *){background-color:color-mix(in oklab,var(--color-gray-800)90%,transparent)}}.dark\:bg-gray-900:is(.dark *){background-color:var(--color-gray-900)}.dark\:bg-green-400:is(.dark *){background-color:var(--color-green-400)}.dark\:bg-green-400\/5:is(.dark *){background-color:#05df720d}@supports (color:color-mix(in lab,red,red)){.dark\:bg-green-400\/5:is(.dark *){background-color:color-mix(in oklab,var(--color-green-400)5%,transparent)}}.dark\:bg-green-400\/10:is(.dark *){background-color:#05df721a}@supports (color:color-mix(in lab,red,red)){.dark\:bg-green-400\/10:is(.dark *){background-color:color-mix(in oklab,var(--color-green-400)10%,transparent)}}.dark\:bg-green-900:is(.dark *){background-color:var(--color-green-900)}.dark\:bg-green-950:is(.dark *){background-color:var(--color-green-950)}.dark\:bg-green-950\/20:is(.dark *){background-color:#032e1533}@supports (color:color-mix(in lab,red,red)){.dark\:bg-green-950\/20:is(.dark *){background-color:color-mix(in oklab,var(--color-green-950)20%,transparent)}}.dark\:bg-green-950\/50:is(.dark *){background-color:#032e1580}@supports (color:color-mix(in lab,red,red)){.dark\:bg-green-950\/50:is(.dark *){background-color:color-mix(in oklab,var(--color-green-950)50%,transparent)}}.dark\:bg-input\/30:is(.dark *){background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-input\/30:is(.dark *){background-color:color-mix(in oklab,var(--input)30%,transparent)}}.dark\:bg-orange-400:is(.dark *){background-color:var(--color-orange-400)}.dark\:bg-orange-900:is(.dark *){background-color:var(--color-orange-900)}.dark\:bg-orange-950:is(.dark *){background-color:var(--color-orange-950)}.dark\:bg-orange-950\/50:is(.dark *){background-color:#44130680}@supports (color:color-mix(in lab,red,red)){.dark\:bg-orange-950\/50:is(.dark *){background-color:color-mix(in oklab,var(--color-orange-950)50%,transparent)}}.dark\:bg-purple-900:is(.dark *){background-color:var(--color-purple-900)}.dark\:bg-red-400:is(.dark *){background-color:var(--color-red-400)}.dark\:bg-red-900:is(.dark *){background-color:var(--color-red-900)}.dark\:bg-red-950:is(.dark *){background-color:var(--color-red-950)}.dark\:bg-red-950\/20:is(.dark *){background-color:#46080933}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-950\/20:is(.dark *){background-color:color-mix(in oklab,var(--color-red-950)20%,transparent)}}.dark\:text-\[\#8B5CF6\]:is(.dark *){color:#8b5cf6}.dark\:text-amber-100:is(.dark *){color:var(--color-amber-100)}.dark\:text-amber-200:is(.dark *){color:var(--color-amber-200)}.dark\:text-amber-300:is(.dark *){color:var(--color-amber-300)}.dark\:text-amber-400:is(.dark *){color:var(--color-amber-400)}.dark\:text-amber-500:is(.dark *){color:var(--color-amber-500)}.dark\:text-blue-200:is(.dark *){color:var(--color-blue-200)}.dark\:text-blue-300:is(.dark *){color:var(--color-blue-300)}.dark\:text-blue-400:is(.dark *){color:var(--color-blue-400)}.dark\:text-blue-500:is(.dark *){color:var(--color-blue-500)}.dark\:text-emerald-200:is(.dark *){color:var(--color-emerald-200)}.dark\:text-emerald-300:is(.dark *){color:var(--color-emerald-300)}.dark\:text-emerald-400:is(.dark *){color:var(--color-emerald-400)}.dark\:text-gray-100:is(.dark *){color:var(--color-gray-100)}.dark\:text-gray-300:is(.dark *){color:var(--color-gray-300)}.dark\:text-gray-400:is(.dark *){color:var(--color-gray-400)}.dark\:text-green-200:is(.dark *){color:var(--color-green-200)}.dark\:text-green-300:is(.dark *){color:var(--color-green-300)}.dark\:text-green-400:is(.dark *){color:var(--color-green-400)}.dark\:text-orange-200:is(.dark *){color:var(--color-orange-200)}.dark\:text-orange-400:is(.dark *){color:var(--color-orange-400)}.dark\:text-purple-400:is(.dark *){color:var(--color-purple-400)}.dark\:text-red-200:is(.dark *){color:var(--color-red-200)}.dark\:text-red-400:is(.dark *){color:var(--color-red-400)}.dark\:text-yellow-400:is(.dark *){color:var(--color-yellow-400)}.dark\:opacity-30:is(.dark *){opacity:.3}@media (hover:hover){.dark\:hover\:bg-\[\#8B5CF6\]\/10:is(.dark *):hover{background-color:#8b5cf61a}.dark\:hover\:bg-accent\/50:is(.dark *):hover{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-accent\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.dark\:hover\:bg-amber-950\/30:is(.dark *):hover{background-color:#4619014d}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-amber-950\/30:is(.dark *):hover{background-color:color-mix(in oklab,var(--color-amber-950)30%,transparent)}}.dark\:hover\:bg-blue-500\/10:is(.dark *):hover{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-blue-500\/10:is(.dark *):hover{background-color:color-mix(in oklab,var(--color-blue-500)10%,transparent)}}.dark\:hover\:bg-destructive\/30:is(.dark *):hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-destructive\/30:is(.dark *):hover{background-color:color-mix(in oklab,var(--destructive)30%,transparent)}}.dark\:hover\:bg-gray-800:is(.dark *):hover{background-color:var(--color-gray-800)}.dark\:hover\:bg-green-400\/10:is(.dark *):hover{background-color:#05df721a}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-green-400\/10:is(.dark *):hover{background-color:color-mix(in oklab,var(--color-green-400)10%,transparent)}}.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--input)50%,transparent)}}}.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.dark\:data-\[state\=checked\]\:bg-primary:is(.dark *)[data-state=checked]{background-color:var(--primary)}.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *)[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *)[data-variant=destructive]:focus{background-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.\[\&_p\]\:leading-relaxed p{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\&_svg\:not\(\[class\*\=\'text-\'\]\)\]\:text-muted-foreground svg:not([class*=text-]){color:var(--muted-foreground)}.\[\.border-b\]\:pb-6.border-b{padding-bottom:calc(var(--spacing)*6)}.\[\.border-t\]\:pt-6.border-t{padding-top:calc(var(--spacing)*6)}:is(.\*\:\[span\]\:last\:flex>*):is(span):last-child{display:flex}:is(.\*\:\[span\]\:last\:items-center>*):is(span):last-child{align-items:center}:is(.\*\:\[span\]\:last\:gap-2>*):is(span):last-child{gap:calc(var(--spacing)*2)}:is(.data-\[variant\=destructive\]\:\*\:\[svg\]\:\!text-destructive[data-variant=destructive]>*):is(svg){color:var(--destructive)!important}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:top-4>svg{top:calc(var(--spacing)*4)}.\[\&\>svg\]\:left-4>svg{left:calc(var(--spacing)*4)}.\[\&\>svg\]\:text-foreground>svg{color:var(--foreground)}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y:-3px;translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:calc(var(--spacing)*7)}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(48% .18 290);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(97% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(97% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(97% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.2% 0 0);--input:oklch(92.2% 0 0);--ring:oklch(70.8% 0 0);--chart-1:oklch(64.6% .222 41.116);--chart-2:oklch(60% .118 184.704);--chart-3:oklch(39.8% .07 227.392);--chart-4:oklch(82.8% .189 84.429);--chart-5:oklch(76.9% .188 70.08);--sidebar:oklch(98.5% 0 0);--sidebar-foreground:oklch(14.5% 0 0);--sidebar-primary:oklch(20.5% 0 0);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(97% 0 0);--sidebar-accent-foreground:oklch(20.5% 0 0);--sidebar-border:oklch(92.2% 0 0);--sidebar-ring:oklch(70.8% 0 0)}.dark{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(20.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(20.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(62% .2 290);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(55.6% 0 0);--chart-1:oklch(48.8% .243 264.376);--chart-2:oklch(69.6% .17 162.48);--chart-3:oklch(76.9% .188 70.08);--chart-4:oklch(62.7% .265 303.9);--chart-5:oklch(64.5% .246 16.439);--sidebar:oklch(20.5% 0 0);--sidebar-foreground:oklch(98.5% 0 0);--sidebar-primary:oklch(48.8% .243 264.376);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(26.9% 0 0);--sidebar-accent-foreground:oklch(98.5% 0 0);--sidebar-border:oklch(100% 0 0/.1);--sidebar-ring:oklch(55.6% 0 0)}.workflow-chat-view .border-green-200{border-color:var(--color-emerald-200)}.workflow-chat-view .bg-green-50{background-color:var(--color-emerald-50)}.workflow-chat-view .bg-green-100{background-color:var(--color-emerald-100)}.workflow-chat-view .text-green-600{color:var(--color-emerald-600)}.workflow-chat-view .text-green-700{color:var(--color-emerald-700)}.workflow-chat-view .text-green-800{color:var(--color-emerald-800)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}.react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #777;--xy-background-pattern-lines-color-default: #777;--xy-background-pattern-cross-color-default: #777;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))} diff --git a/python/packages/devui/agent_framework_devui/ui/assets/index-D_Y1oSGu.js b/python/packages/devui/agent_framework_devui/ui/assets/index-D_Y1oSGu.js deleted file mode 100644 index 85924eb971..0000000000 --- a/python/packages/devui/agent_framework_devui/ui/assets/index-D_Y1oSGu.js +++ /dev/null @@ -1,577 +0,0 @@ -function BE(e,r){for(var o=0;os[l]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))s(l);new MutationObserver(l=>{for(const u of l)if(u.type==="childList")for(const d of u.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&s(d)}).observe(document,{childList:!0,subtree:!0});function o(l){const u={};return l.integrity&&(u.integrity=l.integrity),l.referrerPolicy&&(u.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?u.credentials="include":l.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function s(l){if(l.ep)return;l.ep=!0;const u=o(l);fetch(l.href,u)}})();function qh(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var _m={exports:{}},wi={};/** - * @license React - * react-jsx-runtime.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var bv;function UE(){if(bv)return wi;bv=1;var e=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function o(s,l,u){var d=null;if(u!==void 0&&(d=""+u),l.key!==void 0&&(d=""+l.key),"key"in l){u={};for(var f in l)f!=="key"&&(u[f]=l[f])}else u=l;return l=u.ref,{$$typeof:e,type:s,key:d,ref:l!==void 0?l:null,props:u}}return wi.Fragment=r,wi.jsx=o,wi.jsxs=o,wi}var wv;function PE(){return wv||(wv=1,_m.exports=UE()),_m.exports}var i=PE(),Em={exports:{}},Le={};/** - * @license React - * react.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Nv;function $E(){if(Nv)return Le;Nv=1;var e=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),l=Symbol.for("react.profiler"),u=Symbol.for("react.consumer"),d=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),h=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),g=Symbol.for("react.lazy"),y=Symbol.iterator;function v(T){return T===null||typeof T!="object"?null:(T=y&&T[y]||T["@@iterator"],typeof T=="function"?T:null)}var b={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},S=Object.assign,w={};function j(T,U,X){this.props=T,this.context=U,this.refs=w,this.updater=X||b}j.prototype.isReactComponent={},j.prototype.setState=function(T,U){if(typeof T!="object"&&typeof T!="function"&&T!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,T,U,"setState")},j.prototype.forceUpdate=function(T){this.updater.enqueueForceUpdate(this,T,"forceUpdate")};function k(){}k.prototype=j.prototype;function M(T,U,X){this.props=T,this.context=U,this.refs=w,this.updater=X||b}var E=M.prototype=new k;E.constructor=M,S(E,j.prototype),E.isPureReactComponent=!0;var A=Array.isArray,D={H:null,A:null,T:null,S:null,V:null},L=Object.prototype.hasOwnProperty;function H(T,U,X,ee,se,he){return X=he.ref,{$$typeof:e,type:T,key:U,ref:X!==void 0?X:null,props:he}}function B(T,U){return H(T.type,U,void 0,void 0,void 0,T.props)}function q(T){return typeof T=="object"&&T!==null&&T.$$typeof===e}function F(T){var U={"=":"=0",":":"=2"};return"$"+T.replace(/[=:]/g,function(X){return U[X]})}var K=/\/+/g;function G(T,U){return typeof T=="object"&&T!==null&&T.key!=null?F(""+T.key):U.toString(36)}function te(){}function I(T){switch(T.status){case"fulfilled":return T.value;case"rejected":throw T.reason;default:switch(typeof T.status=="string"?T.then(te,te):(T.status="pending",T.then(function(U){T.status==="pending"&&(T.status="fulfilled",T.value=U)},function(U){T.status==="pending"&&(T.status="rejected",T.reason=U)})),T.status){case"fulfilled":return T.value;case"rejected":throw T.reason}}throw T}function V(T,U,X,ee,se){var he=typeof T;(he==="undefined"||he==="boolean")&&(T=null);var fe=!1;if(T===null)fe=!0;else switch(he){case"bigint":case"string":case"number":fe=!0;break;case"object":switch(T.$$typeof){case e:case r:fe=!0;break;case g:return fe=T._init,V(fe(T._payload),U,X,ee,se)}}if(fe)return se=se(T),fe=ee===""?"."+G(T,0):ee,A(se)?(X="",fe!=null&&(X=fe.replace(K,"$&/")+"/"),V(se,U,X,"",function(xe){return xe})):se!=null&&(q(se)&&(se=B(se,X+(se.key==null||T&&T.key===se.key?"":(""+se.key).replace(K,"$&/")+"/")+fe)),U.push(se)),1;fe=0;var Q=ee===""?".":ee+":";if(A(T))for(var ae=0;ae>>1,T=_[P];if(0>>1;Pl(ee,z))sel(he,ee)?(_[P]=he,_[se]=z,P=se):(_[P]=ee,_[X]=z,P=X);else if(sel(he,z))_[P]=he,_[se]=z,P=se;else break e}}return O}function l(_,O){var z=_.sortIndex-O.sortIndex;return z!==0?z:_.id-O.id}if(e.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var u=performance;e.unstable_now=function(){return u.now()}}else{var d=Date,f=d.now();e.unstable_now=function(){return d.now()-f}}var h=[],p=[],g=1,y=null,v=3,b=!1,S=!1,w=!1,j=!1,k=typeof setTimeout=="function"?setTimeout:null,M=typeof clearTimeout=="function"?clearTimeout:null,E=typeof setImmediate<"u"?setImmediate:null;function A(_){for(var O=o(p);O!==null;){if(O.callback===null)s(p);else if(O.startTime<=_)s(p),O.sortIndex=O.expirationTime,r(h,O);else break;O=o(p)}}function D(_){if(w=!1,A(_),!S)if(o(h)!==null)S=!0,L||(L=!0,G());else{var O=o(p);O!==null&&V(D,O.startTime-_)}}var L=!1,H=-1,B=5,q=-1;function F(){return j?!0:!(e.unstable_now()-q_&&F());){var P=y.callback;if(typeof P=="function"){y.callback=null,v=y.priorityLevel;var T=P(y.expirationTime<=_);if(_=e.unstable_now(),typeof T=="function"){y.callback=T,A(_),O=!0;break t}y===o(h)&&s(h),A(_)}else s(h);y=o(h)}if(y!==null)O=!0;else{var U=o(p);U!==null&&V(D,U.startTime-_),O=!1}}break e}finally{y=null,v=z,b=!1}O=void 0}}finally{O?G():L=!1}}}var G;if(typeof E=="function")G=function(){E(K)};else if(typeof MessageChannel<"u"){var te=new MessageChannel,I=te.port2;te.port1.onmessage=K,G=function(){I.postMessage(null)}}else G=function(){k(K,0)};function V(_,O){H=k(function(){_(e.unstable_now())},O)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(_){_.callback=null},e.unstable_forceFrameRate=function(_){0>_||125<_?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):B=0<_?Math.floor(1e3/_):5},e.unstable_getCurrentPriorityLevel=function(){return v},e.unstable_next=function(_){switch(v){case 1:case 2:case 3:var O=3;break;default:O=v}var z=v;v=O;try{return _()}finally{v=z}},e.unstable_requestPaint=function(){j=!0},e.unstable_runWithPriority=function(_,O){switch(_){case 1:case 2:case 3:case 4:case 5:break;default:_=3}var z=v;v=_;try{return O()}finally{v=z}},e.unstable_scheduleCallback=function(_,O,z){var P=e.unstable_now();switch(typeof z=="object"&&z!==null?(z=z.delay,z=typeof z=="number"&&0P?(_.sortIndex=z,r(p,_),o(h)===null&&_===o(p)&&(w?(M(H),H=-1):w=!0,V(D,z-P))):(_.sortIndex=T,r(h,_),S||b||(S=!0,L||(L=!0,G()))),_},e.unstable_shouldYield=F,e.unstable_wrapCallback=function(_){var O=v;return function(){var z=v;v=O;try{return _.apply(this,arguments)}finally{v=z}}}})(km)),km}var Ev;function qE(){return Ev||(Ev=1,Cm.exports=VE()),Cm.exports}var Am={exports:{}},Lt={};/** - * @license React - * react-dom.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var jv;function YE(){if(jv)return Lt;jv=1;var e=Wi();function r(h){var p="https://react.dev/errors/"+h;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(r){console.error(r)}}return e(),Am.exports=YE(),Am.exports}/** - * @license React - * react-dom-client.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var kv;function GE(){if(kv)return Ni;kv=1;var e=qE(),r=Wi(),o=Eb();function s(t){var n="https://react.dev/errors/"+t;if(1T||(t.current=P[T],P[T]=null,T--)}function ee(t,n){T++,P[T]=t.current,t.current=n}var se=U(null),he=U(null),fe=U(null),Q=U(null);function ae(t,n){switch(ee(fe,n),ee(he,t),ee(se,null),n.nodeType){case 9:case 11:t=(t=n.documentElement)&&(t=t.namespaceURI)?F0(t):0;break;default:if(t=n.tagName,n=n.namespaceURI)n=F0(n),t=Z0(n,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}X(se),ee(se,t)}function xe(){X(se),X(he),X(fe)}function le(t){t.memoizedState!==null&&ee(Q,t);var n=se.current,a=Z0(n,t.type);n!==a&&(ee(he,t),ee(se,a))}function ce(t){he.current===t&&(X(se),X(he)),Q.current===t&&(X(Q),gi._currentValue=z)}var ue=Object.prototype.hasOwnProperty,ge=e.unstable_scheduleCallback,pe=e.unstable_cancelCallback,Be=e.unstable_shouldYield,st=e.unstable_requestPaint,re=e.unstable_now,ve=e.unstable_getCurrentPriorityLevel,ke=e.unstable_ImmediatePriority,De=e.unstable_UserBlockingPriority,be=e.unstable_NormalPriority,Te=e.unstable_LowPriority,Ye=e.unstable_IdlePriority,it=e.log,Tn=e.unstable_setDisableYieldValue,Fe=null,Ue=null;function Qe(t){if(typeof it=="function"&&Tn(t),Ue&&typeof Ue.setStrictMode=="function")try{Ue.setStrictMode(Fe,t)}catch{}}var ht=Math.clz32?Math.clz32:dd,Ft=Math.log,ga=Math.LN2;function dd(t){return t>>>=0,t===0?32:31-(Ft(t)/ga|0)|0}var ns=256,rs=4194304;function Wn(t){var n=t&42;if(n!==0)return n;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t&4194048;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function os(t,n,a){var c=t.pendingLanes;if(c===0)return 0;var m=0,x=t.suspendedLanes,C=t.pingedLanes;t=t.warmLanes;var R=c&134217727;return R!==0?(c=R&~x,c!==0?m=Wn(c):(C&=R,C!==0?m=Wn(C):a||(a=R&~t,a!==0&&(m=Wn(a))))):(R=c&~x,R!==0?m=Wn(R):C!==0?m=Wn(C):a||(a=c&~t,a!==0&&(m=Wn(a)))),m===0?0:n!==0&&n!==m&&(n&x)===0&&(x=m&-m,a=n&-n,x>=a||x===32&&(a&4194048)!==0)?n:m}function xo(t,n){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&n)===0}function fd(t,n){switch(t){case 1:case 2:case 4:case 8:case 64:return n+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return n+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function dl(){var t=ns;return ns<<=1,(ns&4194048)===0&&(ns=256),t}function fl(){var t=rs;return rs<<=1,(rs&62914560)===0&&(rs=4194304),t}function xa(t){for(var n=[],a=0;31>a;a++)n.push(t);return n}function vo(t,n){t.pendingLanes|=n,n!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function md(t,n,a,c,m,x){var C=t.pendingLanes;t.pendingLanes=a,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=a,t.entangledLanes&=a,t.errorRecoveryDisabledLanes&=a,t.shellSuspendCounter=0;var R=t.entanglements,$=t.expirationTimes,J=t.hiddenUpdates;for(a=C&~a;0)":-1m||$[c]!==J[m]){var ie=` -`+$[c].replace(" at new "," at ");return t.displayName&&ie.includes("")&&(ie=ie.replace("",t.displayName)),ie}while(1<=c&&0<=m);break}}}finally{Ea=!1,Error.prepareStackTrace=a}return(a=t?t.displayName||t.name:"")?tr(a):""}function yd(t){switch(t.tag){case 26:case 27:case 5:return tr(t.type);case 16:return tr("Lazy");case 13:return tr("Suspense");case 19:return tr("SuspenseList");case 0:case 15:return ja(t.type,!1);case 11:return ja(t.type.render,!1);case 1:return ja(t.type,!0);case 31:return tr("Activity");default:return""}}function bl(t){try{var n="";do n+=yd(t),t=t.return;while(t);return n}catch(a){return` -Error generating stack: `+a.message+` -`+a.stack}}function Bt(t){switch(typeof t){case"bigint":case"boolean":case"number":case"string":case"undefined":return t;case"object":return t;default:return""}}function wl(t){var n=t.type;return(t=t.nodeName)&&t.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function bd(t){var n=wl(t)?"checked":"value",a=Object.getOwnPropertyDescriptor(t.constructor.prototype,n),c=""+t[n];if(!t.hasOwnProperty(n)&&typeof a<"u"&&typeof a.get=="function"&&typeof a.set=="function"){var m=a.get,x=a.set;return Object.defineProperty(t,n,{configurable:!0,get:function(){return m.call(this)},set:function(C){c=""+C,x.call(this,C)}}),Object.defineProperty(t,n,{enumerable:a.enumerable}),{getValue:function(){return c},setValue:function(C){c=""+C},stopTracking:function(){t._valueTracker=null,delete t[n]}}}}function is(t){t._valueTracker||(t._valueTracker=bd(t))}function Ca(t){if(!t)return!1;var n=t._valueTracker;if(!n)return!0;var a=n.getValue(),c="";return t&&(c=wl(t)?t.checked?"true":"false":t.value),t=c,t!==a?(n.setValue(t),!0):!1}function ls(t){if(t=t||(typeof document<"u"?document:void 0),typeof t>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var wd=/[\n"\\]/g;function Ut(t){return t.replace(wd,function(n){return"\\"+n.charCodeAt(0).toString(16)+" "})}function bo(t,n,a,c,m,x,C,R){t.name="",C!=null&&typeof C!="function"&&typeof C!="symbol"&&typeof C!="boolean"?t.type=C:t.removeAttribute("type"),n!=null?C==="number"?(n===0&&t.value===""||t.value!=n)&&(t.value=""+Bt(n)):t.value!==""+Bt(n)&&(t.value=""+Bt(n)):C!=="submit"&&C!=="reset"||t.removeAttribute("value"),n!=null?ka(t,C,Bt(n)):a!=null?ka(t,C,Bt(a)):c!=null&&t.removeAttribute("value"),m==null&&x!=null&&(t.defaultChecked=!!x),m!=null&&(t.checked=m&&typeof m!="function"&&typeof m!="symbol"),R!=null&&typeof R!="function"&&typeof R!="symbol"&&typeof R!="boolean"?t.name=""+Bt(R):t.removeAttribute("name")}function Nl(t,n,a,c,m,x,C,R){if(x!=null&&typeof x!="function"&&typeof x!="symbol"&&typeof x!="boolean"&&(t.type=x),n!=null||a!=null){if(!(x!=="submit"&&x!=="reset"||n!=null))return;a=a!=null?""+Bt(a):"",n=n!=null?""+Bt(n):a,R||n===t.value||(t.value=n),t.defaultValue=n}c=c??m,c=typeof c!="function"&&typeof c!="symbol"&&!!c,t.checked=R?t.checked:!!c,t.defaultChecked=!!c,C!=null&&typeof C!="function"&&typeof C!="symbol"&&typeof C!="boolean"&&(t.name=C)}function ka(t,n,a){n==="number"&&ls(t.ownerDocument)===t||t.defaultValue===""+a||(t.defaultValue=""+a)}function nr(t,n,a,c){if(t=t.options,n){n={};for(var m=0;m"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),jd=!1;if(rr)try{var Ma={};Object.defineProperty(Ma,"passive",{get:function(){jd=!0}}),window.addEventListener("test",Ma,Ma),window.removeEventListener("test",Ma,Ma)}catch{jd=!1}var Or=null,Cd=null,_l=null;function Qp(){if(_l)return _l;var t,n=Cd,a=n.length,c,m="value"in Or?Or.value:Or.textContent,x=m.length;for(t=0;t=Da),og=" ",sg=!1;function ag(t,n){switch(t){case"keyup":return c_.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function ig(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var fs=!1;function d_(t,n){switch(t){case"compositionend":return ig(n);case"keypress":return n.which!==32?null:(sg=!0,og);case"textInput":return t=n.data,t===og&&sg?null:t;default:return null}}function f_(t,n){if(fs)return t==="compositionend"||!Rd&&ag(t,n)?(t=Qp(),_l=Cd=Or=null,fs=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1=n)return{node:a,offset:n-t};t=c}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=pg(a)}}function xg(t,n){return t&&n?t===n?!0:t&&t.nodeType===3?!1:n&&n.nodeType===3?xg(t,n.parentNode):"contains"in t?t.contains(n):t.compareDocumentPosition?!!(t.compareDocumentPosition(n)&16):!1:!1}function vg(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var n=ls(t.document);n instanceof t.HTMLIFrameElement;){try{var a=typeof n.contentWindow.location.href=="string"}catch{a=!1}if(a)t=n.contentWindow;else break;n=ls(t.document)}return n}function zd(t){var n=t&&t.nodeName&&t.nodeName.toLowerCase();return n&&(n==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||n==="textarea"||t.contentEditable==="true")}var b_=rr&&"documentMode"in document&&11>=document.documentMode,ms=null,Ld=null,Ia=null,Id=!1;function yg(t,n,a){var c=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;Id||ms==null||ms!==ls(c)||(c=ms,"selectionStart"in c&&zd(c)?c={start:c.selectionStart,end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset}),Ia&&La(Ia,c)||(Ia=c,c=hc(Ld,"onSelect"),0>=C,m-=C,sr=1<<32-ht(n)+m|a<x?x:8;var C=_.T,R={};_.T=R,Sf(t,!1,n,a);try{var $=m(),J=_.S;if(J!==null&&J(R,$),$!==null&&typeof $=="object"&&typeof $.then=="function"){var ie=A_($,c);Qa(t,n,ie,en(t))}else Qa(t,n,c,en(t))}catch(me){Qa(t,n,{then:function(){},status:"rejected",reason:me},en())}finally{O.p=x,_.T=C}}function O_(){}function wf(t,n,a,c){if(t.tag!==5)throw Error(s(476));var m=bx(t).queue;yx(t,m,n,z,a===null?O_:function(){return wx(t),a(c)})}function bx(t){var n=t.memoizedState;if(n!==null)return n;n={memoizedState:z,baseState:z,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:cr,lastRenderedState:z},next:null};var a={};return n.next={memoizedState:a,baseState:a,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:cr,lastRenderedState:a},next:null},t.memoizedState=n,t=t.alternate,t!==null&&(t.memoizedState=n),n}function wx(t){var n=bx(t).next.queue;Qa(t,n,{},en())}function Nf(){return zt(gi)}function Nx(){return yt().memoizedState}function Sx(){return yt().memoizedState}function z_(t){for(var n=t.return;n!==null;){switch(n.tag){case 24:case 3:var a=en();t=Ir(a);var c=Hr(n,t,a);c!==null&&(tn(c,n,a),Ga(c,n,a)),n={cache:Wd()},t.payload=n;return}n=n.return}}function L_(t,n,a){var c=en();a={lane:c,revertLane:0,action:a,hasEagerState:!1,eagerState:null,next:null},Fl(t)?Ex(n,a):(a=Pd(t,n,a,c),a!==null&&(tn(a,t,c),jx(a,n,c)))}function _x(t,n,a){var c=en();Qa(t,n,a,c)}function Qa(t,n,a,c){var m={lane:c,revertLane:0,action:a,hasEagerState:!1,eagerState:null,next:null};if(Fl(t))Ex(n,m);else{var x=t.alternate;if(t.lanes===0&&(x===null||x.lanes===0)&&(x=n.lastRenderedReducer,x!==null))try{var C=n.lastRenderedState,R=x(C,a);if(m.hasEagerState=!0,m.eagerState=R,Zt(R,C))return Tl(t,n,m,0),at===null&&Ml(),!1}catch{}finally{}if(a=Pd(t,n,m,c),a!==null)return tn(a,t,c),jx(a,n,c),!0}return!1}function Sf(t,n,a,c){if(c={lane:2,revertLane:tm(),action:c,hasEagerState:!1,eagerState:null,next:null},Fl(t)){if(n)throw Error(s(479))}else n=Pd(t,a,c,2),n!==null&&tn(n,t,2)}function Fl(t){var n=t.alternate;return t===Ie||n!==null&&n===Ie}function Ex(t,n){Ss=$l=!0;var a=t.pending;a===null?n.next=n:(n.next=a.next,a.next=n),t.pending=n}function jx(t,n,a){if((a&4194048)!==0){var c=n.lanes;c&=t.pendingLanes,a|=c,n.lanes=a,va(t,a)}}var Zl={readContext:zt,use:ql,useCallback:pt,useContext:pt,useEffect:pt,useImperativeHandle:pt,useLayoutEffect:pt,useInsertionEffect:pt,useMemo:pt,useReducer:pt,useRef:pt,useState:pt,useDebugValue:pt,useDeferredValue:pt,useTransition:pt,useSyncExternalStore:pt,useId:pt,useHostTransitionStatus:pt,useFormState:pt,useActionState:pt,useOptimistic:pt,useMemoCache:pt,useCacheRefresh:pt},Cx={readContext:zt,use:ql,useCallback:function(t,n){return $t().memoizedState=[t,n===void 0?null:n],t},useContext:zt,useEffect:ux,useImperativeHandle:function(t,n,a){a=a!=null?a.concat([t]):null,Xl(4194308,4,hx.bind(null,n,t),a)},useLayoutEffect:function(t,n){return Xl(4194308,4,t,n)},useInsertionEffect:function(t,n){Xl(4,2,t,n)},useMemo:function(t,n){var a=$t();n=n===void 0?null:n;var c=t();if(Ro){Qe(!0);try{t()}finally{Qe(!1)}}return a.memoizedState=[c,n],c},useReducer:function(t,n,a){var c=$t();if(a!==void 0){var m=a(n);if(Ro){Qe(!0);try{a(n)}finally{Qe(!1)}}}else m=n;return c.memoizedState=c.baseState=m,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:m},c.queue=t,t=t.dispatch=L_.bind(null,Ie,t),[c.memoizedState,t]},useRef:function(t){var n=$t();return t={current:t},n.memoizedState=t},useState:function(t){t=xf(t);var n=t.queue,a=_x.bind(null,Ie,n);return n.dispatch=a,[t.memoizedState,a]},useDebugValue:yf,useDeferredValue:function(t,n){var a=$t();return bf(a,t,n)},useTransition:function(){var t=xf(!1);return t=yx.bind(null,Ie,t.queue,!0,!1),$t().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,n,a){var c=Ie,m=$t();if(We){if(a===void 0)throw Error(s(407));a=a()}else{if(a=n(),at===null)throw Error(s(349));(Ge&124)!==0||Fg(c,n,a)}m.memoizedState=a;var x={value:a,getSnapshot:n};return m.queue=x,ux(Kg.bind(null,c,x,t),[t]),c.flags|=2048,Es(9,Gl(),Zg.bind(null,c,x,a,n),null),a},useId:function(){var t=$t(),n=at.identifierPrefix;if(We){var a=ar,c=sr;a=(c&~(1<<32-ht(c)-1)).toString(32)+a,n="«"+n+"R"+a,a=Vl++,0Me?(Ct=je,je=null):Ct=je.sibling;var Ze=ne(Z,je,W[Me],de);if(Ze===null){je===null&&(je=Ct);break}t&&je&&Ze.alternate===null&&n(Z,je),Y=x(Ze,Y,Me),Pe===null?we=Ze:Pe.sibling=Ze,Pe=Ze,je=Ct}if(Me===W.length)return a(Z,je),We&&jo(Z,Me),we;if(je===null){for(;MeMe?(Ct=je,je=null):Ct=je.sibling;var to=ne(Z,je,Ze.value,de);if(to===null){je===null&&(je=Ct);break}t&&je&&to.alternate===null&&n(Z,je),Y=x(to,Y,Me),Pe===null?we=to:Pe.sibling=to,Pe=to,je=Ct}if(Ze.done)return a(Z,je),We&&jo(Z,Me),we;if(je===null){for(;!Ze.done;Me++,Ze=W.next())Ze=me(Z,Ze.value,de),Ze!==null&&(Y=x(Ze,Y,Me),Pe===null?we=Ze:Pe.sibling=Ze,Pe=Ze);return We&&jo(Z,Me),we}for(je=c(je);!Ze.done;Me++,Ze=W.next())Ze=oe(je,Z,Me,Ze.value,de),Ze!==null&&(t&&Ze.alternate!==null&&je.delete(Ze.key===null?Me:Ze.key),Y=x(Ze,Y,Me),Pe===null?we=Ze:Pe.sibling=Ze,Pe=Ze);return t&&je.forEach(function(HE){return n(Z,HE)}),We&&jo(Z,Me),we}function rt(Z,Y,W,de){if(typeof W=="object"&&W!==null&&W.type===S&&W.key===null&&(W=W.props.children),typeof W=="object"&&W!==null){switch(W.$$typeof){case v:e:{for(var we=W.key;Y!==null;){if(Y.key===we){if(we=W.type,we===S){if(Y.tag===7){a(Z,Y.sibling),de=m(Y,W.props.children),de.return=Z,Z=de;break e}}else if(Y.elementType===we||typeof we=="object"&&we!==null&&we.$$typeof===B&&Ax(we)===Y.type){a(Z,Y.sibling),de=m(Y,W.props),ei(de,W),de.return=Z,Z=de;break e}a(Z,Y);break}else n(Z,Y);Y=Y.sibling}W.type===S?(de=_o(W.props.children,Z.mode,de,W.key),de.return=Z,Z=de):(de=Dl(W.type,W.key,W.props,null,Z.mode,de),ei(de,W),de.return=Z,Z=de)}return C(Z);case b:e:{for(we=W.key;Y!==null;){if(Y.key===we)if(Y.tag===4&&Y.stateNode.containerInfo===W.containerInfo&&Y.stateNode.implementation===W.implementation){a(Z,Y.sibling),de=m(Y,W.children||[]),de.return=Z,Z=de;break e}else{a(Z,Y);break}else n(Z,Y);Y=Y.sibling}de=qd(W,Z.mode,de),de.return=Z,Z=de}return C(Z);case B:return we=W._init,W=we(W._payload),rt(Z,Y,W,de)}if(V(W))return Re(Z,Y,W,de);if(G(W)){if(we=G(W),typeof we!="function")throw Error(s(150));return W=we.call(W),Ae(Z,Y,W,de)}if(typeof W.then=="function")return rt(Z,Y,Kl(W),de);if(W.$$typeof===E)return rt(Z,Y,Il(Z,W),de);Wl(Z,W)}return typeof W=="string"&&W!==""||typeof W=="number"||typeof W=="bigint"?(W=""+W,Y!==null&&Y.tag===6?(a(Z,Y.sibling),de=m(Y,W),de.return=Z,Z=de):(a(Z,Y),de=Vd(W,Z.mode,de),de.return=Z,Z=de),C(Z)):a(Z,Y)}return function(Z,Y,W,de){try{Ja=0;var we=rt(Z,Y,W,de);return js=null,we}catch(je){if(je===qa||je===Bl)throw je;var Pe=Kt(29,je,null,Z.mode);return Pe.lanes=de,Pe.return=Z,Pe}finally{}}}var Cs=Mx(!0),Tx=Mx(!1),mn=U(null),On=null;function Ur(t){var n=t.alternate;ee(Nt,Nt.current&1),ee(mn,t),On===null&&(n===null||Ns.current!==null||n.memoizedState!==null)&&(On=t)}function Rx(t){if(t.tag===22){if(ee(Nt,Nt.current),ee(mn,t),On===null){var n=t.alternate;n!==null&&n.memoizedState!==null&&(On=t)}}else Pr()}function Pr(){ee(Nt,Nt.current),ee(mn,mn.current)}function ur(t){X(mn),On===t&&(On=null),X(Nt)}var Nt=U(0);function Ql(t){for(var n=t;n!==null;){if(n.tag===13){var a=n.memoizedState;if(a!==null&&(a=a.dehydrated,a===null||a.data==="$?"||mm(a)))return n}else if(n.tag===19&&n.memoizedProps.revealOrder!==void 0){if((n.flags&128)!==0)return n}else if(n.child!==null){n.child.return=n,n=n.child;continue}if(n===t)break;for(;n.sibling===null;){if(n.return===null||n.return===t)return null;n=n.return}n.sibling.return=n.return,n=n.sibling}return null}function _f(t,n,a,c){n=t.memoizedState,a=a(c,n),a=a==null?n:g({},n,a),t.memoizedState=a,t.lanes===0&&(t.updateQueue.baseState=a)}var Ef={enqueueSetState:function(t,n,a){t=t._reactInternals;var c=en(),m=Ir(c);m.payload=n,a!=null&&(m.callback=a),n=Hr(t,m,c),n!==null&&(tn(n,t,c),Ga(n,t,c))},enqueueReplaceState:function(t,n,a){t=t._reactInternals;var c=en(),m=Ir(c);m.tag=1,m.payload=n,a!=null&&(m.callback=a),n=Hr(t,m,c),n!==null&&(tn(n,t,c),Ga(n,t,c))},enqueueForceUpdate:function(t,n){t=t._reactInternals;var a=en(),c=Ir(a);c.tag=2,n!=null&&(c.callback=n),n=Hr(t,c,a),n!==null&&(tn(n,t,a),Ga(n,t,a))}};function Dx(t,n,a,c,m,x,C){return t=t.stateNode,typeof t.shouldComponentUpdate=="function"?t.shouldComponentUpdate(c,x,C):n.prototype&&n.prototype.isPureReactComponent?!La(a,c)||!La(m,x):!0}function Ox(t,n,a,c){t=n.state,typeof n.componentWillReceiveProps=="function"&&n.componentWillReceiveProps(a,c),typeof n.UNSAFE_componentWillReceiveProps=="function"&&n.UNSAFE_componentWillReceiveProps(a,c),n.state!==t&&Ef.enqueueReplaceState(n,n.state,null)}function Do(t,n){var a=n;if("ref"in n){a={};for(var c in n)c!=="ref"&&(a[c]=n[c])}if(t=t.defaultProps){a===n&&(a=g({},a));for(var m in t)a[m]===void 0&&(a[m]=t[m])}return a}var Jl=typeof reportError=="function"?reportError:function(t){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var n=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof t=="object"&&t!==null&&typeof t.message=="string"?String(t.message):String(t),error:t});if(!window.dispatchEvent(n))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",t);return}console.error(t)};function zx(t){Jl(t)}function Lx(t){console.error(t)}function Ix(t){Jl(t)}function ec(t,n){try{var a=t.onUncaughtError;a(n.value,{componentStack:n.stack})}catch(c){setTimeout(function(){throw c})}}function Hx(t,n,a){try{var c=t.onCaughtError;c(a.value,{componentStack:a.stack,errorBoundary:n.tag===1?n.stateNode:null})}catch(m){setTimeout(function(){throw m})}}function jf(t,n,a){return a=Ir(a),a.tag=3,a.payload={element:null},a.callback=function(){ec(t,n)},a}function Bx(t){return t=Ir(t),t.tag=3,t}function Ux(t,n,a,c){var m=a.type.getDerivedStateFromError;if(typeof m=="function"){var x=c.value;t.payload=function(){return m(x)},t.callback=function(){Hx(n,a,c)}}var C=a.stateNode;C!==null&&typeof C.componentDidCatch=="function"&&(t.callback=function(){Hx(n,a,c),typeof m!="function"&&(Xr===null?Xr=new Set([this]):Xr.add(this));var R=c.stack;this.componentDidCatch(c.value,{componentStack:R!==null?R:""})})}function H_(t,n,a,c,m){if(a.flags|=32768,c!==null&&typeof c=="object"&&typeof c.then=="function"){if(n=a.alternate,n!==null&&Pa(n,a,m,!0),a=mn.current,a!==null){switch(a.tag){case 13:return On===null?Kf():a.alternate===null&&mt===0&&(mt=3),a.flags&=-257,a.flags|=65536,a.lanes=m,c===ef?a.flags|=16384:(n=a.updateQueue,n===null?a.updateQueue=new Set([c]):n.add(c),Qf(t,c,m)),!1;case 22:return a.flags|=65536,c===ef?a.flags|=16384:(n=a.updateQueue,n===null?(n={transitions:null,markerInstances:null,retryQueue:new Set([c])},a.updateQueue=n):(a=n.retryQueue,a===null?n.retryQueue=new Set([c]):a.add(c)),Qf(t,c,m)),!1}throw Error(s(435,a.tag))}return Qf(t,c,m),Kf(),!1}if(We)return n=mn.current,n!==null?((n.flags&65536)===0&&(n.flags|=256),n.flags|=65536,n.lanes=m,c!==Xd&&(t=Error(s(422),{cause:c}),Ua(cn(t,a)))):(c!==Xd&&(n=Error(s(423),{cause:c}),Ua(cn(n,a))),t=t.current.alternate,t.flags|=65536,m&=-m,t.lanes|=m,c=cn(c,a),m=jf(t.stateNode,c,m),rf(t,m),mt!==4&&(mt=2)),!1;var x=Error(s(520),{cause:c});if(x=cn(x,a),ii===null?ii=[x]:ii.push(x),mt!==4&&(mt=2),n===null)return!0;c=cn(c,a),a=n;do{switch(a.tag){case 3:return a.flags|=65536,t=m&-m,a.lanes|=t,t=jf(a.stateNode,c,t),rf(a,t),!1;case 1:if(n=a.type,x=a.stateNode,(a.flags&128)===0&&(typeof n.getDerivedStateFromError=="function"||x!==null&&typeof x.componentDidCatch=="function"&&(Xr===null||!Xr.has(x))))return a.flags|=65536,m&=-m,a.lanes|=m,m=Bx(m),Ux(m,t,a,c),rf(a,m),!1}a=a.return}while(a!==null);return!1}var Px=Error(s(461)),Et=!1;function kt(t,n,a,c){n.child=t===null?Tx(n,null,a,c):Cs(n,t.child,a,c)}function $x(t,n,a,c,m){a=a.render;var x=n.ref;if("ref"in c){var C={};for(var R in c)R!=="ref"&&(C[R]=c[R])}else C=c;return Mo(n),c=cf(t,n,a,C,x,m),R=uf(),t!==null&&!Et?(df(t,n,m),dr(t,n,m)):(We&&R&&Yd(n),n.flags|=1,kt(t,n,c,m),n.child)}function Vx(t,n,a,c,m){if(t===null){var x=a.type;return typeof x=="function"&&!$d(x)&&x.defaultProps===void 0&&a.compare===null?(n.tag=15,n.type=x,qx(t,n,x,c,m)):(t=Dl(a.type,null,c,n,n.mode,m),t.ref=n.ref,t.return=n,n.child=t)}if(x=t.child,!Of(t,m)){var C=x.memoizedProps;if(a=a.compare,a=a!==null?a:La,a(C,c)&&t.ref===n.ref)return dr(t,n,m)}return n.flags|=1,t=or(x,c),t.ref=n.ref,t.return=n,n.child=t}function qx(t,n,a,c,m){if(t!==null){var x=t.memoizedProps;if(La(x,c)&&t.ref===n.ref)if(Et=!1,n.pendingProps=c=x,Of(t,m))(t.flags&131072)!==0&&(Et=!0);else return n.lanes=t.lanes,dr(t,n,m)}return Cf(t,n,a,c,m)}function Yx(t,n,a){var c=n.pendingProps,m=c.children,x=t!==null?t.memoizedState:null;if(c.mode==="hidden"){if((n.flags&128)!==0){if(c=x!==null?x.baseLanes|a:a,t!==null){for(m=n.child=t.child,x=0;m!==null;)x=x|m.lanes|m.childLanes,m=m.sibling;n.childLanes=x&~c}else n.childLanes=0,n.child=null;return Gx(t,n,c,a)}if((a&536870912)!==0)n.memoizedState={baseLanes:0,cachePool:null},t!==null&&Hl(n,x!==null?x.cachePool:null),x!==null?qg(n,x):sf(),Rx(n);else return n.lanes=n.childLanes=536870912,Gx(t,n,x!==null?x.baseLanes|a:a,a)}else x!==null?(Hl(n,x.cachePool),qg(n,x),Pr(),n.memoizedState=null):(t!==null&&Hl(n,null),sf(),Pr());return kt(t,n,m,a),n.child}function Gx(t,n,a,c){var m=Jd();return m=m===null?null:{parent:wt._currentValue,pool:m},n.memoizedState={baseLanes:a,cachePool:m},t!==null&&Hl(n,null),sf(),Rx(n),t!==null&&Pa(t,n,c,!0),null}function tc(t,n){var a=n.ref;if(a===null)t!==null&&t.ref!==null&&(n.flags|=4194816);else{if(typeof a!="function"&&typeof a!="object")throw Error(s(284));(t===null||t.ref!==a)&&(n.flags|=4194816)}}function Cf(t,n,a,c,m){return Mo(n),a=cf(t,n,a,c,void 0,m),c=uf(),t!==null&&!Et?(df(t,n,m),dr(t,n,m)):(We&&c&&Yd(n),n.flags|=1,kt(t,n,a,m),n.child)}function Xx(t,n,a,c,m,x){return Mo(n),n.updateQueue=null,a=Gg(n,c,a,m),Yg(t),c=uf(),t!==null&&!Et?(df(t,n,x),dr(t,n,x)):(We&&c&&Yd(n),n.flags|=1,kt(t,n,a,x),n.child)}function Fx(t,n,a,c,m){if(Mo(n),n.stateNode===null){var x=xs,C=a.contextType;typeof C=="object"&&C!==null&&(x=zt(C)),x=new a(c,x),n.memoizedState=x.state!==null&&x.state!==void 0?x.state:null,x.updater=Ef,n.stateNode=x,x._reactInternals=n,x=n.stateNode,x.props=c,x.state=n.memoizedState,x.refs={},tf(n),C=a.contextType,x.context=typeof C=="object"&&C!==null?zt(C):xs,x.state=n.memoizedState,C=a.getDerivedStateFromProps,typeof C=="function"&&(_f(n,a,C,c),x.state=n.memoizedState),typeof a.getDerivedStateFromProps=="function"||typeof x.getSnapshotBeforeUpdate=="function"||typeof x.UNSAFE_componentWillMount!="function"&&typeof x.componentWillMount!="function"||(C=x.state,typeof x.componentWillMount=="function"&&x.componentWillMount(),typeof x.UNSAFE_componentWillMount=="function"&&x.UNSAFE_componentWillMount(),C!==x.state&&Ef.enqueueReplaceState(x,x.state,null),Fa(n,c,x,m),Xa(),x.state=n.memoizedState),typeof x.componentDidMount=="function"&&(n.flags|=4194308),c=!0}else if(t===null){x=n.stateNode;var R=n.memoizedProps,$=Do(a,R);x.props=$;var J=x.context,ie=a.contextType;C=xs,typeof ie=="object"&&ie!==null&&(C=zt(ie));var me=a.getDerivedStateFromProps;ie=typeof me=="function"||typeof x.getSnapshotBeforeUpdate=="function",R=n.pendingProps!==R,ie||typeof x.UNSAFE_componentWillReceiveProps!="function"&&typeof x.componentWillReceiveProps!="function"||(R||J!==C)&&Ox(n,x,c,C),Lr=!1;var ne=n.memoizedState;x.state=ne,Fa(n,c,x,m),Xa(),J=n.memoizedState,R||ne!==J||Lr?(typeof me=="function"&&(_f(n,a,me,c),J=n.memoizedState),($=Lr||Dx(n,a,$,c,ne,J,C))?(ie||typeof x.UNSAFE_componentWillMount!="function"&&typeof x.componentWillMount!="function"||(typeof x.componentWillMount=="function"&&x.componentWillMount(),typeof x.UNSAFE_componentWillMount=="function"&&x.UNSAFE_componentWillMount()),typeof x.componentDidMount=="function"&&(n.flags|=4194308)):(typeof x.componentDidMount=="function"&&(n.flags|=4194308),n.memoizedProps=c,n.memoizedState=J),x.props=c,x.state=J,x.context=C,c=$):(typeof x.componentDidMount=="function"&&(n.flags|=4194308),c=!1)}else{x=n.stateNode,nf(t,n),C=n.memoizedProps,ie=Do(a,C),x.props=ie,me=n.pendingProps,ne=x.context,J=a.contextType,$=xs,typeof J=="object"&&J!==null&&($=zt(J)),R=a.getDerivedStateFromProps,(J=typeof R=="function"||typeof x.getSnapshotBeforeUpdate=="function")||typeof x.UNSAFE_componentWillReceiveProps!="function"&&typeof x.componentWillReceiveProps!="function"||(C!==me||ne!==$)&&Ox(n,x,c,$),Lr=!1,ne=n.memoizedState,x.state=ne,Fa(n,c,x,m),Xa();var oe=n.memoizedState;C!==me||ne!==oe||Lr||t!==null&&t.dependencies!==null&&Ll(t.dependencies)?(typeof R=="function"&&(_f(n,a,R,c),oe=n.memoizedState),(ie=Lr||Dx(n,a,ie,c,ne,oe,$)||t!==null&&t.dependencies!==null&&Ll(t.dependencies))?(J||typeof x.UNSAFE_componentWillUpdate!="function"&&typeof x.componentWillUpdate!="function"||(typeof x.componentWillUpdate=="function"&&x.componentWillUpdate(c,oe,$),typeof x.UNSAFE_componentWillUpdate=="function"&&x.UNSAFE_componentWillUpdate(c,oe,$)),typeof x.componentDidUpdate=="function"&&(n.flags|=4),typeof x.getSnapshotBeforeUpdate=="function"&&(n.flags|=1024)):(typeof x.componentDidUpdate!="function"||C===t.memoizedProps&&ne===t.memoizedState||(n.flags|=4),typeof x.getSnapshotBeforeUpdate!="function"||C===t.memoizedProps&&ne===t.memoizedState||(n.flags|=1024),n.memoizedProps=c,n.memoizedState=oe),x.props=c,x.state=oe,x.context=$,c=ie):(typeof x.componentDidUpdate!="function"||C===t.memoizedProps&&ne===t.memoizedState||(n.flags|=4),typeof x.getSnapshotBeforeUpdate!="function"||C===t.memoizedProps&&ne===t.memoizedState||(n.flags|=1024),c=!1)}return x=c,tc(t,n),c=(n.flags&128)!==0,x||c?(x=n.stateNode,a=c&&typeof a.getDerivedStateFromError!="function"?null:x.render(),n.flags|=1,t!==null&&c?(n.child=Cs(n,t.child,null,m),n.child=Cs(n,null,a,m)):kt(t,n,a,m),n.memoizedState=x.state,t=n.child):t=dr(t,n,m),t}function Zx(t,n,a,c){return Ba(),n.flags|=256,kt(t,n,a,c),n.child}var kf={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function Af(t){return{baseLanes:t,cachePool:Lg()}}function Mf(t,n,a){return t=t!==null?t.childLanes&~a:0,n&&(t|=hn),t}function Kx(t,n,a){var c=n.pendingProps,m=!1,x=(n.flags&128)!==0,C;if((C=x)||(C=t!==null&&t.memoizedState===null?!1:(Nt.current&2)!==0),C&&(m=!0,n.flags&=-129),C=(n.flags&32)!==0,n.flags&=-33,t===null){if(We){if(m?Ur(n):Pr(),We){var R=ft,$;if($=R){e:{for($=R,R=Dn;$.nodeType!==8;){if(!R){R=null;break e}if($=wn($.nextSibling),$===null){R=null;break e}}R=$}R!==null?(n.memoizedState={dehydrated:R,treeContext:Eo!==null?{id:sr,overflow:ar}:null,retryLane:536870912,hydrationErrors:null},$=Kt(18,null,null,0),$.stateNode=R,$.return=n,n.child=$,It=n,ft=null,$=!0):$=!1}$||ko(n)}if(R=n.memoizedState,R!==null&&(R=R.dehydrated,R!==null))return mm(R)?n.lanes=32:n.lanes=536870912,null;ur(n)}return R=c.children,c=c.fallback,m?(Pr(),m=n.mode,R=nc({mode:"hidden",children:R},m),c=_o(c,m,a,null),R.return=n,c.return=n,R.sibling=c,n.child=R,m=n.child,m.memoizedState=Af(a),m.childLanes=Mf(t,C,a),n.memoizedState=kf,c):(Ur(n),Tf(n,R))}if($=t.memoizedState,$!==null&&(R=$.dehydrated,R!==null)){if(x)n.flags&256?(Ur(n),n.flags&=-257,n=Rf(t,n,a)):n.memoizedState!==null?(Pr(),n.child=t.child,n.flags|=128,n=null):(Pr(),m=c.fallback,R=n.mode,c=nc({mode:"visible",children:c.children},R),m=_o(m,R,a,null),m.flags|=2,c.return=n,m.return=n,c.sibling=m,n.child=c,Cs(n,t.child,null,a),c=n.child,c.memoizedState=Af(a),c.childLanes=Mf(t,C,a),n.memoizedState=kf,n=m);else if(Ur(n),mm(R)){if(C=R.nextSibling&&R.nextSibling.dataset,C)var J=C.dgst;C=J,c=Error(s(419)),c.stack="",c.digest=C,Ua({value:c,source:null,stack:null}),n=Rf(t,n,a)}else if(Et||Pa(t,n,a,!1),C=(a&t.childLanes)!==0,Et||C){if(C=at,C!==null&&(c=a&-a,c=(c&42)!==0?1:ya(c),c=(c&(C.suspendedLanes|a))!==0?0:c,c!==0&&c!==$.retryLane))throw $.retryLane=c,gs(t,c),tn(C,t,c),Px;R.data==="$?"||Kf(),n=Rf(t,n,a)}else R.data==="$?"?(n.flags|=192,n.child=t.child,n=null):(t=$.treeContext,ft=wn(R.nextSibling),It=n,We=!0,Co=null,Dn=!1,t!==null&&(dn[fn++]=sr,dn[fn++]=ar,dn[fn++]=Eo,sr=t.id,ar=t.overflow,Eo=n),n=Tf(n,c.children),n.flags|=4096);return n}return m?(Pr(),m=c.fallback,R=n.mode,$=t.child,J=$.sibling,c=or($,{mode:"hidden",children:c.children}),c.subtreeFlags=$.subtreeFlags&65011712,J!==null?m=or(J,m):(m=_o(m,R,a,null),m.flags|=2),m.return=n,c.return=n,c.sibling=m,n.child=c,c=m,m=n.child,R=t.child.memoizedState,R===null?R=Af(a):($=R.cachePool,$!==null?(J=wt._currentValue,$=$.parent!==J?{parent:J,pool:J}:$):$=Lg(),R={baseLanes:R.baseLanes|a,cachePool:$}),m.memoizedState=R,m.childLanes=Mf(t,C,a),n.memoizedState=kf,c):(Ur(n),a=t.child,t=a.sibling,a=or(a,{mode:"visible",children:c.children}),a.return=n,a.sibling=null,t!==null&&(C=n.deletions,C===null?(n.deletions=[t],n.flags|=16):C.push(t)),n.child=a,n.memoizedState=null,a)}function Tf(t,n){return n=nc({mode:"visible",children:n},t.mode),n.return=t,t.child=n}function nc(t,n){return t=Kt(22,t,null,n),t.lanes=0,t.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null},t}function Rf(t,n,a){return Cs(n,t.child,null,a),t=Tf(n,n.pendingProps.children),t.flags|=2,n.memoizedState=null,t}function Wx(t,n,a){t.lanes|=n;var c=t.alternate;c!==null&&(c.lanes|=n),Zd(t.return,n,a)}function Df(t,n,a,c,m){var x=t.memoizedState;x===null?t.memoizedState={isBackwards:n,rendering:null,renderingStartTime:0,last:c,tail:a,tailMode:m}:(x.isBackwards=n,x.rendering=null,x.renderingStartTime=0,x.last=c,x.tail=a,x.tailMode=m)}function Qx(t,n,a){var c=n.pendingProps,m=c.revealOrder,x=c.tail;if(kt(t,n,c.children,a),c=Nt.current,(c&2)!==0)c=c&1|2,n.flags|=128;else{if(t!==null&&(t.flags&128)!==0)e:for(t=n.child;t!==null;){if(t.tag===13)t.memoizedState!==null&&Wx(t,a,n);else if(t.tag===19)Wx(t,a,n);else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===n)break e;for(;t.sibling===null;){if(t.return===null||t.return===n)break e;t=t.return}t.sibling.return=t.return,t=t.sibling}c&=1}switch(ee(Nt,c),m){case"forwards":for(a=n.child,m=null;a!==null;)t=a.alternate,t!==null&&Ql(t)===null&&(m=a),a=a.sibling;a=m,a===null?(m=n.child,n.child=null):(m=a.sibling,a.sibling=null),Df(n,!1,m,a,x);break;case"backwards":for(a=null,m=n.child,n.child=null;m!==null;){if(t=m.alternate,t!==null&&Ql(t)===null){n.child=m;break}t=m.sibling,m.sibling=a,a=m,m=t}Df(n,!0,a,null,x);break;case"together":Df(n,!1,null,null,void 0);break;default:n.memoizedState=null}return n.child}function dr(t,n,a){if(t!==null&&(n.dependencies=t.dependencies),Gr|=n.lanes,(a&n.childLanes)===0)if(t!==null){if(Pa(t,n,a,!1),(a&n.childLanes)===0)return null}else return null;if(t!==null&&n.child!==t.child)throw Error(s(153));if(n.child!==null){for(t=n.child,a=or(t,t.pendingProps),n.child=a,a.return=n;t.sibling!==null;)t=t.sibling,a=a.sibling=or(t,t.pendingProps),a.return=n;a.sibling=null}return n.child}function Of(t,n){return(t.lanes&n)!==0?!0:(t=t.dependencies,!!(t!==null&&Ll(t)))}function B_(t,n,a){switch(n.tag){case 3:ae(n,n.stateNode.containerInfo),zr(n,wt,t.memoizedState.cache),Ba();break;case 27:case 5:le(n);break;case 4:ae(n,n.stateNode.containerInfo);break;case 10:zr(n,n.type,n.memoizedProps.value);break;case 13:var c=n.memoizedState;if(c!==null)return c.dehydrated!==null?(Ur(n),n.flags|=128,null):(a&n.child.childLanes)!==0?Kx(t,n,a):(Ur(n),t=dr(t,n,a),t!==null?t.sibling:null);Ur(n);break;case 19:var m=(t.flags&128)!==0;if(c=(a&n.childLanes)!==0,c||(Pa(t,n,a,!1),c=(a&n.childLanes)!==0),m){if(c)return Qx(t,n,a);n.flags|=128}if(m=n.memoizedState,m!==null&&(m.rendering=null,m.tail=null,m.lastEffect=null),ee(Nt,Nt.current),c)break;return null;case 22:case 23:return n.lanes=0,Yx(t,n,a);case 24:zr(n,wt,t.memoizedState.cache)}return dr(t,n,a)}function Jx(t,n,a){if(t!==null)if(t.memoizedProps!==n.pendingProps)Et=!0;else{if(!Of(t,a)&&(n.flags&128)===0)return Et=!1,B_(t,n,a);Et=(t.flags&131072)!==0}else Et=!1,We&&(n.flags&1048576)!==0&&Ag(n,zl,n.index);switch(n.lanes=0,n.tag){case 16:e:{t=n.pendingProps;var c=n.elementType,m=c._init;if(c=m(c._payload),n.type=c,typeof c=="function")$d(c)?(t=Do(c,t),n.tag=1,n=Fx(null,n,c,t,a)):(n.tag=0,n=Cf(null,n,c,t,a));else{if(c!=null){if(m=c.$$typeof,m===A){n.tag=11,n=$x(null,n,c,t,a);break e}else if(m===H){n.tag=14,n=Vx(null,n,c,t,a);break e}}throw n=I(c)||c,Error(s(306,n,""))}}return n;case 0:return Cf(t,n,n.type,n.pendingProps,a);case 1:return c=n.type,m=Do(c,n.pendingProps),Fx(t,n,c,m,a);case 3:e:{if(ae(n,n.stateNode.containerInfo),t===null)throw Error(s(387));c=n.pendingProps;var x=n.memoizedState;m=x.element,nf(t,n),Fa(n,c,null,a);var C=n.memoizedState;if(c=C.cache,zr(n,wt,c),c!==x.cache&&Kd(n,[wt],a,!0),Xa(),c=C.element,x.isDehydrated)if(x={element:c,isDehydrated:!1,cache:C.cache},n.updateQueue.baseState=x,n.memoizedState=x,n.flags&256){n=Zx(t,n,c,a);break e}else if(c!==m){m=cn(Error(s(424)),n),Ua(m),n=Zx(t,n,c,a);break e}else{switch(t=n.stateNode.containerInfo,t.nodeType){case 9:t=t.body;break;default:t=t.nodeName==="HTML"?t.ownerDocument.body:t}for(ft=wn(t.firstChild),It=n,We=!0,Co=null,Dn=!0,a=Tx(n,null,c,a),n.child=a;a;)a.flags=a.flags&-3|4096,a=a.sibling}else{if(Ba(),c===m){n=dr(t,n,a);break e}kt(t,n,c,a)}n=n.child}return n;case 26:return tc(t,n),t===null?(a=rv(n.type,null,n.pendingProps,null))?n.memoizedState=a:We||(a=n.type,t=n.pendingProps,c=gc(fe.current).createElement(a),c[_t]=n,c[Ot]=t,Mt(c,a,t),xt(c),n.stateNode=c):n.memoizedState=rv(n.type,t.memoizedProps,n.pendingProps,t.memoizedState),null;case 27:return le(n),t===null&&We&&(c=n.stateNode=ev(n.type,n.pendingProps,fe.current),It=n,Dn=!0,m=ft,Kr(n.type)?(hm=m,ft=wn(c.firstChild)):ft=m),kt(t,n,n.pendingProps.children,a),tc(t,n),t===null&&(n.flags|=4194304),n.child;case 5:return t===null&&We&&((m=c=ft)&&(c=mE(c,n.type,n.pendingProps,Dn),c!==null?(n.stateNode=c,It=n,ft=wn(c.firstChild),Dn=!1,m=!0):m=!1),m||ko(n)),le(n),m=n.type,x=n.pendingProps,C=t!==null?t.memoizedProps:null,c=x.children,um(m,x)?c=null:C!==null&&um(m,C)&&(n.flags|=32),n.memoizedState!==null&&(m=cf(t,n,T_,null,null,a),gi._currentValue=m),tc(t,n),kt(t,n,c,a),n.child;case 6:return t===null&&We&&((t=a=ft)&&(a=hE(a,n.pendingProps,Dn),a!==null?(n.stateNode=a,It=n,ft=null,t=!0):t=!1),t||ko(n)),null;case 13:return Kx(t,n,a);case 4:return ae(n,n.stateNode.containerInfo),c=n.pendingProps,t===null?n.child=Cs(n,null,c,a):kt(t,n,c,a),n.child;case 11:return $x(t,n,n.type,n.pendingProps,a);case 7:return kt(t,n,n.pendingProps,a),n.child;case 8:return kt(t,n,n.pendingProps.children,a),n.child;case 12:return kt(t,n,n.pendingProps.children,a),n.child;case 10:return c=n.pendingProps,zr(n,n.type,c.value),kt(t,n,c.children,a),n.child;case 9:return m=n.type._context,c=n.pendingProps.children,Mo(n),m=zt(m),c=c(m),n.flags|=1,kt(t,n,c,a),n.child;case 14:return Vx(t,n,n.type,n.pendingProps,a);case 15:return qx(t,n,n.type,n.pendingProps,a);case 19:return Qx(t,n,a);case 31:return c=n.pendingProps,a=n.mode,c={mode:c.mode,children:c.children},t===null?(a=nc(c,a),a.ref=n.ref,n.child=a,a.return=n,n=a):(a=or(t.child,c),a.ref=n.ref,n.child=a,a.return=n,n=a),n;case 22:return Yx(t,n,a);case 24:return Mo(n),c=zt(wt),t===null?(m=Jd(),m===null&&(m=at,x=Wd(),m.pooledCache=x,x.refCount++,x!==null&&(m.pooledCacheLanes|=a),m=x),n.memoizedState={parent:c,cache:m},tf(n),zr(n,wt,m)):((t.lanes&a)!==0&&(nf(t,n),Fa(n,null,null,a),Xa()),m=t.memoizedState,x=n.memoizedState,m.parent!==c?(m={parent:c,cache:c},n.memoizedState=m,n.lanes===0&&(n.memoizedState=n.updateQueue.baseState=m),zr(n,wt,c)):(c=x.cache,zr(n,wt,c),c!==m.cache&&Kd(n,[wt],a,!0))),kt(t,n,n.pendingProps.children,a),n.child;case 29:throw n.pendingProps}throw Error(s(156,n.tag))}function fr(t){t.flags|=4}function e0(t,n){if(n.type!=="stylesheet"||(n.state.loading&4)!==0)t.flags&=-16777217;else if(t.flags|=16777216,!lv(n)){if(n=mn.current,n!==null&&((Ge&4194048)===Ge?On!==null:(Ge&62914560)!==Ge&&(Ge&536870912)===0||n!==On))throw Ya=ef,Ig;t.flags|=8192}}function rc(t,n){n!==null&&(t.flags|=4),t.flags&16384&&(n=t.tag!==22?fl():536870912,t.lanes|=n,Ts|=n)}function ti(t,n){if(!We)switch(t.tailMode){case"hidden":n=t.tail;for(var a=null;n!==null;)n.alternate!==null&&(a=n),n=n.sibling;a===null?t.tail=null:a.sibling=null;break;case"collapsed":a=t.tail;for(var c=null;a!==null;)a.alternate!==null&&(c=a),a=a.sibling;c===null?n||t.tail===null?t.tail=null:t.tail.sibling=null:c.sibling=null}}function ut(t){var n=t.alternate!==null&&t.alternate.child===t.child,a=0,c=0;if(n)for(var m=t.child;m!==null;)a|=m.lanes|m.childLanes,c|=m.subtreeFlags&65011712,c|=m.flags&65011712,m.return=t,m=m.sibling;else for(m=t.child;m!==null;)a|=m.lanes|m.childLanes,c|=m.subtreeFlags,c|=m.flags,m.return=t,m=m.sibling;return t.subtreeFlags|=c,t.childLanes=a,n}function U_(t,n,a){var c=n.pendingProps;switch(Gd(n),n.tag){case 31:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return ut(n),null;case 1:return ut(n),null;case 3:return a=n.stateNode,c=null,t!==null&&(c=t.memoizedState.cache),n.memoizedState.cache!==c&&(n.flags|=2048),lr(wt),xe(),a.pendingContext&&(a.context=a.pendingContext,a.pendingContext=null),(t===null||t.child===null)&&(Ha(n)?fr(n):t===null||t.memoizedState.isDehydrated&&(n.flags&256)===0||(n.flags|=1024,Rg())),ut(n),null;case 26:return a=n.memoizedState,t===null?(fr(n),a!==null?(ut(n),e0(n,a)):(ut(n),n.flags&=-16777217)):a?a!==t.memoizedState?(fr(n),ut(n),e0(n,a)):(ut(n),n.flags&=-16777217):(t.memoizedProps!==c&&fr(n),ut(n),n.flags&=-16777217),null;case 27:ce(n),a=fe.current;var m=n.type;if(t!==null&&n.stateNode!=null)t.memoizedProps!==c&&fr(n);else{if(!c){if(n.stateNode===null)throw Error(s(166));return ut(n),null}t=se.current,Ha(n)?Mg(n):(t=ev(m,c,a),n.stateNode=t,fr(n))}return ut(n),null;case 5:if(ce(n),a=n.type,t!==null&&n.stateNode!=null)t.memoizedProps!==c&&fr(n);else{if(!c){if(n.stateNode===null)throw Error(s(166));return ut(n),null}if(t=se.current,Ha(n))Mg(n);else{switch(m=gc(fe.current),t){case 1:t=m.createElementNS("http://www.w3.org/2000/svg",a);break;case 2:t=m.createElementNS("http://www.w3.org/1998/Math/MathML",a);break;default:switch(a){case"svg":t=m.createElementNS("http://www.w3.org/2000/svg",a);break;case"math":t=m.createElementNS("http://www.w3.org/1998/Math/MathML",a);break;case"script":t=m.createElement("div"),t.innerHTML=" - + +
diff --git a/python/packages/devui/agent_framework_devui/ui/vite.svg b/python/packages/devui/agent_framework_devui/ui/vite.svg deleted file mode 100644 index e7b8dfb1b2..0000000000 --- a/python/packages/devui/agent_framework_devui/ui/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/python/packages/devui/frontend/index.html b/python/packages/devui/frontend/index.html index 5290b853eb..e957a1547f 100644 --- a/python/packages/devui/frontend/index.html +++ b/python/packages/devui/frontend/index.html @@ -2,12 +2,12 @@ - + Agent Framework Dev UI
- + diff --git a/python/packages/devui/frontend/public/vite.svg b/python/packages/devui/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb1b2..0000000000 --- a/python/packages/devui/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/python/packages/devui/frontend/src/components/features/agent/agent-view.tsx b/python/packages/devui/frontend/src/components/features/agent/agent-view.tsx index dc7f59ec62..ea0941a531 100644 --- a/python/packages/devui/frontend/src/components/features/agent/agent-view.tsx +++ b/python/packages/devui/frontend/src/components/features/agent/agent-view.tsx @@ -45,6 +45,7 @@ import type { ExtendedResponseStreamEvent, } from "@/types"; import { useDevUIStore } from "@/stores"; +import { loadStreamingState } from "@/services/streaming-state"; type DebugEventHandler = (event: ExtendedResponseStreamEvent | "clear") => void; @@ -229,7 +230,6 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { const scrollAreaRef = useRef(null); const messagesEndRef = useRef(null); - const accumulatedText = useRef(""); const textareaRef = useRef(null); const currentMessageUsage = useRef<{ total_tokens: number; @@ -237,6 +237,7 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { output_tokens: number; } | null>(null); const userJustSentMessage = useRef(false); + const accumulatedTextRef = useRef(""); // Auto-scroll to bottom when new items arrive useEffect(() => { @@ -281,33 +282,270 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { // Load conversations when agent changes useEffect(() => { + // Resume streaming after page refresh + const resumeStreaming = async ( + assistantMessage: import("@/types/openai").ConversationMessage, + conversation: Conversation, + agent: AgentInfo + ) => { + // Load the stored state to get the response ID + const storedState = loadStreamingState(conversation.id); + if (!storedState || !storedState.responseId) { + setIsStreaming(false); + return; + } + + try { + // Use the stored responseId to resume the stream via GET /v1/responses/{responseId} + const openAIRequest: import("@/types/agent-framework").AgentFrameworkRequest = { + model: agent.id, + input: [], // Not needed for resume (using GET) + stream: true, + conversation: conversation.id, + }; + + // Pass the response ID explicitly to trigger GET request + const streamGenerator = apiClient.streamAgentExecutionOpenAIDirect( + agent.id, + openAIRequest, + conversation.id, + storedState.responseId // Pass response ID for resume + ); + + for await (const openAIEvent of streamGenerator) { + // Pass all events to debug panel + onDebugEvent(openAIEvent); + + // Handle response.completed event + if (openAIEvent.type === "response.completed") { + const completedEvent = openAIEvent as import("@/types/openai").ResponseCompletedEvent; + const usage = completedEvent.response?.usage; + + if (usage) { + currentMessageUsage.current = { + input_tokens: usage.input_tokens, + output_tokens: usage.output_tokens, + total_tokens: usage.total_tokens, + }; + } + continue; + } + + // Handle response.failed event + if (openAIEvent.type === "response.failed") { + const failedEvent = openAIEvent as import("@/types/openai").ResponseFailedEvent; + const error = failedEvent.response?.error; + const errorMessage = error + ? typeof error === "object" && "message" in error + ? (error as any).message + : JSON.stringify(error) + : "Request failed"; + + const currentItems = useDevUIStore.getState().chatItems; + setChatItems(currentItems.map((item) => + item.id === assistantMessage.id && item.type === "message" + ? { + ...item, + content: [ + { + type: "text", + text: accumulatedTextRef.current || errorMessage, + } as import("@/types/openai").MessageTextContent, + ], + status: "incomplete" as const, + } + : item + )); + setIsStreaming(false); + return; + } + + // Handle function approval request events + if (openAIEvent.type === "response.function_approval.requested") { + const approvalEvent = openAIEvent as import("@/types/openai").ResponseFunctionApprovalRequestedEvent; + setPendingApprovals([ + ...useDevUIStore.getState().pendingApprovals, + { + request_id: approvalEvent.request_id, + function_call: approvalEvent.function_call, + }, + ]); + continue; + } + + // Handle function approval response events + if (openAIEvent.type === "response.function_approval.responded") { + const responseEvent = openAIEvent as import("@/types/openai").ResponseFunctionApprovalRespondedEvent; + setPendingApprovals( + useDevUIStore.getState().pendingApprovals.filter((a) => a.request_id !== responseEvent.request_id) + ); + continue; + } + + // Handle error events + if (openAIEvent.type === "error") { + const errorEvent = openAIEvent as ExtendedResponseStreamEvent & { message?: string }; + const errorMessage = errorEvent.message || "An error occurred"; + + const currentItems = useDevUIStore.getState().chatItems; + setChatItems(currentItems.map((item) => + item.id === assistantMessage.id && item.type === "message" + ? { + ...item, + content: [ + { + type: "text", + text: accumulatedTextRef.current || errorMessage, + } as import("@/types/openai").MessageTextContent, + ], + status: "incomplete" as const, + } + : item + )); + setIsStreaming(false); + return; + } + + // Handle text delta events + if ( + openAIEvent.type === "response.output_text.delta" && + "delta" in openAIEvent && + openAIEvent.delta + ) { + accumulatedTextRef.current += openAIEvent.delta; + + const currentItems = useDevUIStore.getState().chatItems; + setChatItems(currentItems.map((item) => + item.id === assistantMessage.id && item.type === "message" + ? { + ...item, + content: [ + { + type: "text", + text: accumulatedTextRef.current, + } as import("@/types/openai").MessageTextContent, + ], + status: "in_progress" as const, + } + : item + )); + } + } + + // Stream ended - mark as complete + const finalUsage = currentMessageUsage.current; + + const currentItems = useDevUIStore.getState().chatItems; + setChatItems(currentItems.map((item) => + item.id === assistantMessage.id && item.type === "message" + ? { + ...item, + status: "completed" as const, + usage: finalUsage || undefined, + } + : item + )); + setIsStreaming(false); + + if (finalUsage) { + updateConversationUsage(finalUsage.total_tokens); + } + + currentMessageUsage.current = null; + } catch (error) { + const currentItems = useDevUIStore.getState().chatItems; + setChatItems(currentItems.map((item) => + item.id === assistantMessage.id && item.type === "message" + ? { + ...item, + content: [ + { + type: "text", + text: `Error resuming stream: ${ + error instanceof Error ? error.message : "Unknown error" + }`, + } as import("@/types/openai").MessageTextContent, + ], + status: "incomplete" as const, + } + : item + )); + setIsStreaming(false); + } + }; + const loadConversations = async () => { if (!selectedAgent) return; setLoadingConversations(true); try { - // Step 1: Try to list conversations from backend (DevUI extension) - // This works with DevUI backend but fails with OpenAI/Azure (they don't have list endpoint) + // Step 1: Always try to list conversations from backend first + // This ensures we get the latest data from the server try { const { data: conversations } = await apiClient.listConversations( selectedAgent.id ); + // Backend successfully returned conversations list + setAvailableConversations(conversations); + if (conversations.length > 0) { // Found conversations on backend - use most recent const mostRecent = conversations[0]; - setAvailableConversations(conversations); setCurrentConversation(mostRecent); // Load conversation items from backend try { - const { data: items } = await apiClient.listConversationItems( - mostRecent.id - ); + // Load all conversation items with pagination + let allItems: unknown[] = []; + let hasMore = true; + let after: string | undefined = undefined; + + while (hasMore) { + const result = await apiClient.listConversationItems( + mostRecent.id, + { order: "asc", after } // Load in chronological order (oldest first) + ); + allItems = allItems.concat(result.data); + hasMore = result.has_more; + + // Get the last item's ID for pagination + if (hasMore && result.data.length > 0) { + const lastItem = result.data[result.data.length - 1] as { id?: string }; + after = lastItem.id; + } + } // Use OpenAI ConversationItems directly (no conversion!) - setChatItems(items as import("@/types/openai").ConversationItem[]); + setChatItems(allItems as import("@/types/openai").ConversationItem[]); setIsStreaming(false); + + // Check for incomplete stream and resume if needed + const state = loadStreamingState(mostRecent.id); + + if (state && !state.completed) { + accumulatedTextRef.current = state.accumulatedText || ""; + // Add assistant message with resumed text + const assistantMsg: import("@/types/openai").ConversationMessage = { + id: state.lastMessageId || `assistant-${Date.now()}`, + type: "message", + role: "assistant", + content: state.accumulatedText ? [{ type: "text", text: state.accumulatedText }] : [], + status: "in_progress", + }; + setChatItems([...allItems as import("@/types/openai").ConversationItem[], assistantMsg]); + setIsStreaming(true); + + // Resume streaming from where we left off + setTimeout(() => { + resumeStreaming(assistantMsg, mostRecent, selectedAgent); + }, 100); + } + + // Scroll to bottom after loading conversation + setTimeout(() => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + }, 100); } catch { // 404 means conversation exists but has no items yet (newly created) // This is normal - just start with empty chat @@ -316,11 +554,6 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { setIsStreaming(false); } - // Cache to localStorage for faster future loads - localStorage.setItem( - `devui_convs_${selectedAgent.id}`, - JSON.stringify(conversations) - ); return; } } catch { @@ -371,9 +604,6 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { setAvailableConversations([newConversation]); setChatItems([]); setIsStreaming(false); - - // Save to localStorage - localStorage.setItem(cachedKey, JSON.stringify([newConversation])); } catch { setAvailableConversations([]); setChatItems([]); @@ -387,10 +617,12 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { setChatItems([]); setIsStreaming(false); setCurrentConversation(undefined); - accumulatedText.current = ""; + accumulatedTextRef.current = ""; loadConversations(); - }, [selectedAgent, setLoadingConversations, setAvailableConversations, setCurrentConversation, setChatItems, setIsStreaming]); + // currentConversation is intentionally excluded - this effect should only run when agent changes + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedAgent, onDebugEvent, setChatItems, setIsStreaming, setLoadingConversations, setAvailableConversations, setCurrentConversation, setPendingApprovals, updateConversationUsage]); // Handle file uploads const handleFilesSelected = async (files: File[]) => { @@ -626,16 +858,11 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { setIsStreaming(false); // Reset conversation usage by setting it to initial state useDevUIStore.setState({ conversationUsage: { total_tokens: 0, message_count: 0 } }); - accumulatedText.current = ""; - - // Update localStorage cache with new conversation - const cachedKey = `devui_convs_${selectedAgent.id}`; - const updated = [newConversation, ...availableConversations]; - localStorage.setItem(cachedKey, JSON.stringify(updated)); + accumulatedTextRef.current = ""; } catch { // Failed to create conversation } - }, [selectedAgent, availableConversations, setCurrentConversation, setAvailableConversations, setChatItems, setIsStreaming]); + }, [selectedAgent, setCurrentConversation, setAvailableConversations, setChatItems, setIsStreaming]); // Handle conversation deletion const handleDeleteConversation = useCallback( @@ -660,15 +887,6 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { ); setAvailableConversations(updatedConversations); - // Update localStorage cache - if (selectedAgent) { - const cachedKey = `devui_convs_${selectedAgent.id}`; - localStorage.setItem( - cachedKey, - JSON.stringify(updatedConversations) - ); - } - // If deleted conversation was selected, switch to another conversation or clear chat if (currentConversation?.id === conversationId) { if (updatedConversations.length > 0) { @@ -683,7 +901,7 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { setChatItems([]); setIsStreaming(false); useDevUIStore.setState({ conversationUsage: { total_tokens: 0, message_count: 0 } }); - accumulatedText.current = ""; + accumulatedTextRef.current = ""; } } @@ -694,7 +912,7 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { alert("Failed to delete conversation. Please try again."); } }, - [availableConversations, currentConversation, selectedAgent, onDebugEvent, setAvailableConversations, setCurrentConversation, setChatItems, setIsStreaming] + [availableConversations, currentConversation, onDebugEvent, setAvailableConversations, setCurrentConversation, setChatItems, setIsStreaming] ); // Handle conversation selection @@ -711,11 +929,28 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { onDebugEvent("clear"); try { - // Load conversation history from backend - const result = await apiClient.listConversationItems(conversationId); + // Load conversation history from backend with pagination + let allItems: unknown[] = []; + let hasMore = true; + let after: string | undefined = undefined; + + while (hasMore) { + const result = await apiClient.listConversationItems(conversationId, { + order: "asc", // Load in chronological order (oldest first) + after, + }); + allItems = allItems.concat(result.data); + hasMore = result.has_more; + + // Get the last item's ID for pagination + if (hasMore && result.data.length > 0) { + const lastItem = result.data[result.data.length - 1] as { id?: string }; + after = lastItem.id; + } + } // Use OpenAI ConversationItems directly (no conversion!) - const items = result.data as import("@/types/openai").ConversationItem[]; + const items = allItems as import("@/types/openai").ConversationItem[]; setChatItems(items); setIsStreaming(false); @@ -727,6 +962,27 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { message_count: items.length, } }); + + // Check for incomplete stream and restore accumulated text + const state = loadStreamingState(conversationId); + if (state?.accumulatedText) { + accumulatedTextRef.current = state.accumulatedText; + // Add assistant message with resumed text - streaming will continue automatically + const assistantMsg: import("@/types/openai").ConversationMessage = { + id: `assistant-${Date.now()}`, + type: "message", + role: "assistant", + content: [{ type: "output_text", text: state.accumulatedText }], + status: "in_progress", + }; + setChatItems([...items, assistantMsg]); + setIsStreaming(true); + } + + // Scroll to bottom after loading conversation + setTimeout(() => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + }, 100); } catch { // 404 means conversation doesn't exist or has no items yet // This can happen if server restarted (in-memory store cleared) @@ -736,7 +992,7 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { useDevUIStore.setState({ conversationUsage: { total_tokens: 0, message_count: 0 } }); } - accumulatedText.current = ""; + accumulatedTextRef.current = ""; }, [availableConversations, onDebugEvent, setCurrentConversation, setChatItems, setIsStreaming] ); @@ -851,13 +1107,18 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { } } + // Clear any previous streaming state for this conversation before starting new message + if (conversationToUse?.id) { + apiClient.clearStreamingState(conversationToUse.id); + } + const apiRequest = { input: request.input, conversation_id: conversationToUse?.id, }; // Clear text accumulator for new response - accumulatedText.current = ""; + accumulatedTextRef.current = ""; // Use OpenAI-compatible API streaming - direct event handling const streamGenerator = apiClient.streamAgentExecutionOpenAI( @@ -884,6 +1145,35 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { continue; // Continue processing other events } + // Handle response.failed event + if (openAIEvent.type === "response.failed") { + const failedEvent = openAIEvent as import("@/types/openai").ResponseFailedEvent; + const error = failedEvent.response?.error; + const errorMessage = error + ? typeof error === "object" && "message" in error + ? (error as any).message + : JSON.stringify(error) + : "Request failed"; + + const currentItems = useDevUIStore.getState().chatItems; + setChatItems(currentItems.map((item) => + item.id === assistantMessage.id && item.type === "message" + ? { + ...item, + content: [ + { + type: "text", + text: accumulatedTextRef.current || errorMessage, + } as import("@/types/openai").MessageTextContent, + ], + status: "incomplete" as const, + } + : item + )); + setIsStreaming(false); + return; + } + // Handle function approval request events if (openAIEvent.type === "response.function_approval.requested") { const approvalEvent = openAIEvent as import("@/types/openai").ResponseFunctionApprovalRequestedEvent; @@ -943,7 +1233,7 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { "delta" in openAIEvent && openAIEvent.delta ) { - accumulatedText.current += openAIEvent.delta; + accumulatedTextRef.current += openAIEvent.delta; // Update assistant message with accumulated content const currentItems = useDevUIStore.getState().chatItems; @@ -954,7 +1244,7 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) { content: [ { type: "text", - text: accumulatedText.current, + text: accumulatedTextRef.current, } as import("@/types/openai").MessageTextContent, ], status: "in_progress" as const, diff --git a/python/packages/devui/frontend/src/components/features/agent/message-renderers/OpenAIContentRenderer.tsx b/python/packages/devui/frontend/src/components/features/agent/message-renderers/OpenAIContentRenderer.tsx index 8d266be40f..3871376945 100644 --- a/python/packages/devui/frontend/src/components/features/agent/message-renderers/OpenAIContentRenderer.tsx +++ b/python/packages/devui/frontend/src/components/features/agent/message-renderers/OpenAIContentRenderer.tsx @@ -23,7 +23,7 @@ interface ContentRendererProps { // Text content renderer function TextContentRenderer({ content, className, isStreaming }: ContentRendererProps) { - if (content.type !== "text") return null; + if (content.type !== "text" && content.type !== "input_text" && content.type !== "output_text") return null; const text = content.text; @@ -160,6 +160,8 @@ function FileContentRenderer({ content, className }: ContentRendererProps) { export function OpenAIContentRenderer({ content, className, isStreaming }: ContentRendererProps) { switch (content.type) { case "text": + case "input_text": + case "output_text": return ; case "input_image": return ; diff --git a/python/packages/devui/frontend/src/components/features/workflow/workflow-view.tsx b/python/packages/devui/frontend/src/components/features/workflow/workflow-view.tsx index 43cf1ac509..1ca95048db 100644 --- a/python/packages/devui/frontend/src/components/features/workflow/workflow-view.tsx +++ b/python/packages/devui/frontend/src/components/features/workflow/workflow-view.tsx @@ -554,6 +554,10 @@ export function WorkflowView({ try { const request = { input_data: inputData }; + // Clear any previous streaming state before starting new workflow execution + // Note: Workflows don't use conversation IDs, so we use workflow ID as the key + apiClient.clearStreamingState(selectedWorkflow.id); + // Use OpenAI-compatible API streaming - direct event handling const streamGenerator = apiClient.streamWorkflowExecutionOpenAI( selectedWorkflow.id, diff --git a/python/packages/devui/frontend/src/main.tsx b/python/packages/devui/frontend/src/main.tsx index 27db649a06..572a406006 100644 --- a/python/packages/devui/frontend/src/main.tsx +++ b/python/packages/devui/frontend/src/main.tsx @@ -3,6 +3,10 @@ import { createRoot } from 'react-dom/client' import './index.css' import App from './App.tsx' import { ThemeProvider } from "./components/theme-provider" +import { initStreamingState } from "./services/api" + +// Initialize streaming state management (clears expired states) +initStreamingState(); createRoot(document.getElementById('root')!).render( diff --git a/python/packages/devui/frontend/src/services/api.ts b/python/packages/devui/frontend/src/services/api.ts index 8a685cf5aa..6cfcff5666 100644 --- a/python/packages/devui/frontend/src/services/api.ts +++ b/python/packages/devui/frontend/src/services/api.ts @@ -14,6 +14,12 @@ import type { } from "@/types"; import type { AgentFrameworkRequest } from "@/types/agent-framework"; import type { ExtendedResponseStreamEvent } from "@/types/openai"; +import { + loadStreamingState, + updateStreamingState, + markStreamingCompleted, + clearStreamingState, +} from "./streaming-state"; // Backend API response type - polymorphic entity that can be agent or workflow // This matches the Python Pydantic EntityInfo model which has all fields optional @@ -57,9 +63,27 @@ const DEFAULT_API_BASE_URL = ? import.meta.env.VITE_API_BASE_URL : "http://localhost:8080"; +// Retry configuration for streaming +const RETRY_INTERVAL_MS = 1000; // Retry every second +const MAX_RETRY_ATTEMPTS = 600; // Max 600 retries (10 minutes total) + // Get backend URL from localStorage or default function getBackendUrl(): string { - return localStorage.getItem("devui_backend_url") || DEFAULT_API_BASE_URL; + const stored = localStorage.getItem("devui_backend_url"); + if (stored) return stored; + + // If VITE_API_BASE_URL is explicitly set to empty string, use relative path + // This allows the frontend to call the same host it's served from + if (import.meta.env.VITE_API_BASE_URL === "") { + return ""; + } + + return DEFAULT_API_BASE_URL; +} + +// Helper to sleep for a given duration +function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); } class ApiClient { @@ -272,6 +296,8 @@ class ApiClient { await this.request(`/v1/conversations/${conversationId}`, { method: "DELETE", }); + // Clear streaming state when conversation is deleted + clearStreamingState(conversationId); return true; } catch { return false; @@ -297,99 +323,252 @@ class ApiClient { // OpenAI-compatible streaming methods using /v1/responses endpoint - // Stream agent execution using OpenAI format with simplified routing - async *streamAgentExecutionOpenAI( - agentId: string, - request: RunAgentRequest + // Private helper method that handles the actual streaming with retry logic + private async *streamOpenAIResponse( + openAIRequest: AgentFrameworkRequest, + conversationId?: string, + resumeResponseId?: string ): AsyncGenerator { - const openAIRequest: AgentFrameworkRequest = { - model: agentId, // Model IS the entity_id (simplified routing!) - input: request.input, // Direct OpenAI ResponseInputParam - stream: true, - conversation: request.conversation_id, // OpenAI standard conversation param - }; - - return yield* this.streamAgentExecutionOpenAIDirect(agentId, openAIRequest); - } - - // Stream agent execution using direct OpenAI format - async *streamAgentExecutionOpenAIDirect( - _agentId: string, - openAIRequest: AgentFrameworkRequest - ): AsyncGenerator { - - const response = await fetch(`${this.baseUrl}/v1/responses`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "text/event-stream", - }, - body: JSON.stringify(openAIRequest), - }); - - if (!response.ok) { - // Try to extract detailed error message from response body - let errorMessage = `Request failed with status ${response.status}`; - try { - const errorBody = await response.json(); - if (errorBody.error && errorBody.error.message) { - errorMessage = errorBody.error.message; - } else if (errorBody.detail) { - errorMessage = errorBody.detail; + let lastSequenceNumber = -1; + let retryCount = 0; + let hasYieldedAnyEvent = false; + let currentResponseId: string | undefined = resumeResponseId; + let lastMessageId: string | undefined = undefined; + + // Try to resume from stored state if conversation ID is provided + if (conversationId) { + const storedState = loadStreamingState(conversationId); + if (storedState) { + // Use stored response ID if no explicit one provided + if (!resumeResponseId) { + currentResponseId = storedState.responseId; + } + + lastSequenceNumber = storedState.lastSequenceNumber; + lastMessageId = storedState.lastMessageId; + + // Replay stored events only if we're not explicitly resuming + // (explicit resume means the caller already has the events) + if (!resumeResponseId) { + for (const event of storedState.events) { + hasYieldedAnyEvent = true; + yield event; + } + } else { + // Mark that we've already seen events up to this sequence number + hasYieldedAnyEvent = storedState.events.length > 0; } - } catch { - // Fallback to generic message if parsing fails } - throw new Error(errorMessage); - } - - const reader = response.body?.getReader(); - if (!reader) { - throw new Error("Response body is not readable"); } - const decoder = new TextDecoder(); - let buffer = ""; - - try { - while (true) { - const { done, value } = await reader.read(); + while (retryCount <= MAX_RETRY_ATTEMPTS) { + try { + // If we have a response_id from a previous attempt, use GET endpoint to resume + // Otherwise, use POST to create a new response + let response: Response; + if (currentResponseId) { + const params = new URLSearchParams(); + params.set("stream", "true"); + if (lastSequenceNumber >= 0) { + params.set("starting_after", lastSequenceNumber.toString()); + } + const url = `${this.baseUrl}/v1/responses/${currentResponseId}?${params.toString()}`; + response = await fetch(url, { + method: "GET", + headers: { + Accept: "text/event-stream", + }, + }); + } else { + const url = `${this.baseUrl}/v1/responses`; + response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "text/event-stream", + }, + body: JSON.stringify(openAIRequest), + }); + } - if (done) { - break; + if (!response.ok) { + // Try to extract detailed error message from response body + let errorMessage = `Request failed with status ${response.status}`; + try { + const errorBody = await response.json(); + if (errorBody.error && errorBody.error.message) { + errorMessage = errorBody.error.message; + } else if (errorBody.detail) { + errorMessage = errorBody.detail; + } + } catch { + // Fallback to generic message if parsing fails + } + throw new Error(errorMessage); } - buffer += decoder.decode(value, { stream: true }); + const reader = response.body?.getReader(); + if (!reader) { + throw new Error("Response body is not readable"); + } - // Parse SSE events - const lines = buffer.split("\n"); - buffer = lines.pop() || ""; // Keep incomplete line in buffer + const decoder = new TextDecoder(); + let buffer = ""; - for (const line of lines) { - if (line.startsWith("data: ")) { - const dataStr = line.slice(6); + try { + while (true) { + const { done, value } = await reader.read(); - // Handle [DONE] signal - if (dataStr === "[DONE]") { + if (done) { + // Stream completed successfully + if (conversationId) { + markStreamingCompleted(conversationId); + } return; } - try { - const openAIEvent: ExtendedResponseStreamEvent = - JSON.parse(dataStr); - yield openAIEvent; // Direct pass-through - no conversion! - } catch (e) { - console.error("Failed to parse OpenAI SSE event:", e); + buffer += decoder.decode(value, { stream: true }); + + // Parse SSE events + const lines = buffer.split("\n"); + buffer = lines.pop() || ""; // Keep incomplete line in buffer + + for (const line of lines) { + if (line.startsWith("data: ")) { + const dataStr = line.slice(6); + + // Handle [DONE] signal + if (dataStr === "[DONE]") { + if (conversationId) { + markStreamingCompleted(conversationId); + } + return; + } + + try { + const openAIEvent: ExtendedResponseStreamEvent = + JSON.parse(dataStr); + + // Capture response_id if present in the event for use in retries + if ("response" in openAIEvent && openAIEvent.response && typeof openAIEvent.response === "object" && "id" in openAIEvent.response) { + const newResponseId = openAIEvent.response.id as string; + if (!currentResponseId || currentResponseId !== newResponseId) { + currentResponseId = newResponseId; + } + } else if ("id" in openAIEvent && typeof openAIEvent.id === "string" && openAIEvent.id.startsWith("resp_")) { + const newResponseId = openAIEvent.id; + if (!currentResponseId || currentResponseId !== newResponseId) { + currentResponseId = newResponseId; + } + } + + // Track last message ID if present (for user/assistant messages) + if ("item_id" in openAIEvent && openAIEvent.item_id) { + lastMessageId = openAIEvent.item_id; + } + + // Check for sequence number restart (server restarted response) + const eventSeq = "sequence_number" in openAIEvent ? openAIEvent.sequence_number : undefined; + if (eventSeq !== undefined) { + // If we've received events before and sequence restarted from 0/1 + if (hasYieldedAnyEvent && eventSeq <= 1 && lastSequenceNumber > 1) { + // Server restarted the response - clear old state and start fresh + if (conversationId) { + clearStreamingState(conversationId); + } + yield { + type: "error", + message: "Connection lost - previous response failed. Starting new response.", + } as ExtendedResponseStreamEvent; + lastSequenceNumber = eventSeq; + hasYieldedAnyEvent = true; + + // Save new event to storage + if (conversationId && currentResponseId) { + updateStreamingState(conversationId, openAIEvent, currentResponseId, lastMessageId); + } + + yield openAIEvent; + } + // Skip events we've already seen (resume from last position) + else if (eventSeq <= lastSequenceNumber) { + continue; // Skip duplicate event + } else { + lastSequenceNumber = eventSeq; + hasYieldedAnyEvent = true; + + // Save event to storage before yielding + if (conversationId && currentResponseId) { + updateStreamingState(conversationId, openAIEvent, currentResponseId, lastMessageId); + } + + yield openAIEvent; + } + } else { + // No sequence number - just yield the event + hasYieldedAnyEvent = true; + + // Still save to storage if we have conversation context + if (conversationId && currentResponseId) { + updateStreamingState(conversationId, openAIEvent, currentResponseId, lastMessageId); + } + + yield openAIEvent; + } + } catch (e) { + console.error("Failed to parse OpenAI SSE event:", e); + } + } } } + } finally { + reader.releaseLock(); } + } catch (error) { + // Network error occurred - prepare to retry + retryCount++; + + if (retryCount > MAX_RETRY_ATTEMPTS) { + // Max retries exceeded - give up + throw new Error( + `Connection failed after ${MAX_RETRY_ATTEMPTS} retry attempts: ${error instanceof Error ? error.message : String(error)}` + ); + } + + // Wait before retrying + await sleep(RETRY_INTERVAL_MS); + // Loop will retry with GET if we have response_id, otherwise POST } - } finally { - reader.releaseLock(); } } - // Stream workflow execution using OpenAI format - direct event pass-through + // Stream agent execution using OpenAI format with simplified routing + async *streamAgentExecutionOpenAI( + agentId: string, + request: RunAgentRequest, + resumeResponseId?: string + ): AsyncGenerator { + const openAIRequest: AgentFrameworkRequest = { + model: agentId, // Model IS the entity_id (simplified routing!) + input: request.input, // Direct OpenAI ResponseInputParam + stream: true, + conversation: request.conversation_id, // OpenAI standard conversation param + }; + + return yield* this.streamAgentExecutionOpenAIDirect(agentId, openAIRequest, request.conversation_id, resumeResponseId); + } + + // Stream agent execution using direct OpenAI format + async *streamAgentExecutionOpenAIDirect( + _agentId: string, + openAIRequest: AgentFrameworkRequest, + conversationId?: string, + resumeResponseId?: string + ): AsyncGenerator { + yield* this.streamOpenAIResponse(openAIRequest, conversationId, resumeResponseId); + } + + // Stream workflow execution using OpenAI format async *streamWorkflowExecutionOpenAI( workflowId: string, request: RunWorkflowRequest @@ -402,75 +581,7 @@ class ApiClient { conversation: request.conversation_id, // Include conversation if present }; - const response = await fetch(`${this.baseUrl}/v1/responses`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "text/event-stream", - }, - body: JSON.stringify(openAIRequest), - }); - - if (!response.ok) { - // Try to extract detailed error message from response body - let errorMessage = `Request failed with status ${response.status}`; - try { - const errorBody = await response.json(); - if (errorBody.error && errorBody.error.message) { - errorMessage = errorBody.error.message; - } else if (errorBody.detail) { - errorMessage = errorBody.detail; - } - } catch { - // Fallback to generic message if parsing fails - } - throw new Error(errorMessage); - } - - const reader = response.body?.getReader(); - if (!reader) { - throw new Error("Response body is not readable"); - } - - const decoder = new TextDecoder(); - let buffer = ""; - - try { - while (true) { - const { done, value } = await reader.read(); - - if (done) { - break; - } - - buffer += decoder.decode(value, { stream: true }); - - // Parse SSE events - const lines = buffer.split("\n"); - buffer = lines.pop() || ""; // Keep incomplete line in buffer - - for (const line of lines) { - if (line.startsWith("data: ")) { - const dataStr = line.slice(6); - - // Handle [DONE] signal - if (dataStr === "[DONE]") { - return; - } - - try { - const openAIEvent: ExtendedResponseStreamEvent = - JSON.parse(dataStr); - yield openAIEvent; // Direct pass-through - no conversion! - } catch (e) { - console.error("Failed to parse OpenAI SSE event:", e); - } - } - } - } - } finally { - reader.releaseLock(); - } + yield* this.streamOpenAIResponse(openAIRequest, request.conversation_id); } // REMOVED: Legacy streaming methods - use streamAgentExecutionOpenAI and streamWorkflowExecutionOpenAI instead @@ -503,8 +614,16 @@ class ApiClient { body: JSON.stringify(request), }); } + + // Clear streaming state for a conversation (e.g., when starting a new message) + clearStreamingState(conversationId: string): void { + clearStreamingState(conversationId); + } } // Export singleton instance export const apiClient = new ApiClient(); export { ApiClient }; + +// Export streaming state init function +export { initStreamingState } from "./streaming-state"; diff --git a/python/packages/devui/frontend/src/services/streaming-state.ts b/python/packages/devui/frontend/src/services/streaming-state.ts new file mode 100644 index 0000000000..86116b2adf --- /dev/null +++ b/python/packages/devui/frontend/src/services/streaming-state.ts @@ -0,0 +1,199 @@ +/** + * Streaming State Persistence + * + * Manages browser storage of streaming response state to enable: + * - Resume interrupted streams after page refresh + * - Replay cached events before fetching new ones + * - Graceful recovery from network disconnections + */ + +import type { ExtendedResponseStreamEvent } from "@/types/openai"; + +export interface StreamingState { + conversationId: string; + responseId: string; + lastMessageId?: string; + lastSequenceNumber: number; + events: ExtendedResponseStreamEvent[]; + timestamp: number; // When this state was last updated + completed: boolean; // Whether the stream completed successfully + accumulatedText?: string; // Accumulated text content for quick restoration +} + +const STORAGE_KEY_PREFIX = "devui_streaming_state_"; +const STATE_EXPIRY_MS = 24 * 60 * 60 * 1000; // 24 hours + +/** + * Storage key for a specific conversation + */ +function getStorageKey(conversationId: string): string { + return `${STORAGE_KEY_PREFIX}${conversationId}`; +} + +/** + * Extract accumulated text from events (for quick restoration) + */ +function extractAccumulatedText(events: ExtendedResponseStreamEvent[]): string { + let text = ""; + for (const event of events) { + if (event.type === "response.output_text.delta" && "delta" in event) { + text += event.delta; + } + } + return text; +} + +/** + * Save streaming state to browser storage + */ +export function saveStreamingState(state: StreamingState): void { + try { + const key = getStorageKey(state.conversationId); + const data = JSON.stringify(state); + localStorage.setItem(key, data); + } catch (error) { + console.error("Failed to save streaming state:", error); + // If storage is full, try to clear old states + try { + clearExpiredStreamingStates(); + // Try again + const key = getStorageKey(state.conversationId); + const data = JSON.stringify(state); + localStorage.setItem(key, data); + } catch { + console.error("Failed to save streaming state even after cleanup"); + } + } +} + +/** + * Load streaming state from browser storage + */ +export function loadStreamingState(conversationId: string): StreamingState | null { + try { + const key = getStorageKey(conversationId); + const data = localStorage.getItem(key); + + if (!data) { + return null; + } + + const state: StreamingState = JSON.parse(data); + + // Check if state has expired + const age = Date.now() - state.timestamp; + if (age > STATE_EXPIRY_MS) { + clearStreamingState(conversationId); + return null; + } + + // If stream was completed, no need to resume + if (state.completed) { + return null; + } + + return state; + } catch (error) { + console.error("Failed to load streaming state:", error); + return null; + } +} + +/** + * Update streaming state with a new event + */ +export function updateStreamingState( + conversationId: string, + event: ExtendedResponseStreamEvent, + responseId: string, + lastMessageId?: string +): void { + try { + const existing = loadStreamingState(conversationId); + const sequenceNumber = "sequence_number" in event ? event.sequence_number : undefined; + + const newEvents = existing ? [...existing.events, event] : [event]; + + const state: StreamingState = { + conversationId, + responseId, + lastMessageId, + lastSequenceNumber: sequenceNumber ?? (existing?.lastSequenceNumber ?? -1), + events: newEvents, + timestamp: Date.now(), + completed: event.type === "response.completed" || event.type === "response.failed", + accumulatedText: extractAccumulatedText(newEvents), + }; + + saveStreamingState(state); + } catch (error) { + console.error("Failed to update streaming state:", error); + } +} + +/** + * Mark streaming state as completed + */ +export function markStreamingCompleted(conversationId: string): void { + try { + const existing = loadStreamingState(conversationId); + if (existing) { + existing.completed = true; + existing.timestamp = Date.now(); + saveStreamingState(existing); + } + } catch (error) { + console.error("Failed to mark streaming as completed:", error); + } +} + +/** + * Clear streaming state for a conversation + */ +export function clearStreamingState(conversationId: string): void { + try { + const key = getStorageKey(conversationId); + localStorage.removeItem(key); + } catch (error) { + console.error("Failed to clear streaming state:", error); + } +} + +/** + * Clear all expired streaming states + */ +export function clearExpiredStreamingStates(): void { + try { + const keys = Object.keys(localStorage); + const now = Date.now(); + + for (const key of keys) { + if (key.startsWith(STORAGE_KEY_PREFIX)) { + try { + const data = localStorage.getItem(key); + if (data) { + const state: StreamingState = JSON.parse(data); + const age = now - state.timestamp; + + if (age > STATE_EXPIRY_MS || state.completed) { + localStorage.removeItem(key); + } + } + } catch { + // Invalid state, remove it + localStorage.removeItem(key); + } + } + } + } catch (error) { + console.error("Failed to clear expired streaming states:", error); + } +} + +/** + * Initialize streaming state management (call on app startup) + */ +export function initStreamingState(): void { + // Clear expired states on startup + clearExpiredStreamingStates(); +} diff --git a/python/packages/devui/frontend/src/types/openai.ts b/python/packages/devui/frontend/src/types/openai.ts index e4df1a1bf8..ad6e613dbc 100644 --- a/python/packages/devui/frontend/src/types/openai.ts +++ b/python/packages/devui/frontend/src/types/openai.ts @@ -347,6 +347,18 @@ export interface MessageTextContent { text: string; } +export interface MessageInputTextContent { + type: "input_text"; + text: string; +} + +export interface MessageOutputTextContent { + type: "output_text"; + text: string; + annotations?: any[]; + logprobs?: any[]; +} + export interface MessageInputImage { type: "input_image"; image_url: string; @@ -376,6 +388,8 @@ export interface MessageFunctionApprovalResponseContent { export type MessageContent = | MessageTextContent + | MessageInputTextContent + | MessageOutputTextContent | MessageInputImage | MessageInputFile | MessageFunctionApprovalResponseContent; diff --git a/python/packages/devui/frontend/vite.config.ts b/python/packages/devui/frontend/vite.config.ts index 010f098001..49a54b477d 100644 --- a/python/packages/devui/frontend/vite.config.ts +++ b/python/packages/devui/frontend/vite.config.ts @@ -5,6 +5,7 @@ import path from "path"; // https://vite.dev/config/ export default defineConfig({ + base: "", plugins: [react(), tailwindcss()], resolve: { alias: { @@ -12,12 +13,20 @@ export default defineConfig({ }, }, build: { + commonjsOptions: { + // Enable deterministic builds, as per https://github.com/vitejs/vite/issues/13672#issuecomment-1784110536 + strictRequires: true, + }, outDir: "../agent_framework_devui/ui", emptyOutDir: true, rollupOptions: { output: { manualChunks: undefined, inlineDynamicImports: true, + // Use static filenames instead of content hashes + entryFileNames: "assets/index.js", + chunkFileNames: "assets/[name].js", + assetFileNames: "assets/[name].[ext]", }, }, }, diff --git a/python/packages/devui/frontend/yarn.lock b/python/packages/devui/frontend/yarn.lock index 00efde8b6f..a6793bb713 100644 --- a/python/packages/devui/frontend/yarn.lock +++ b/python/packages/devui/frontend/yarn.lock @@ -24,7 +24,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz" integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== -"@babel/core@^7.28.3": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.28.3": version "7.28.3" resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz" integrity sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ== @@ -168,156 +168,9 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" -"@emnapi/core@^1.4.3", "@emnapi/core@^1.4.5": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.5.0.tgz#85cd84537ec989cebb2343606a1ee663ce4edaf0" - integrity sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg== - dependencies: - "@emnapi/wasi-threads" "1.1.0" - tslib "^2.4.0" - -"@emnapi/runtime@^1.4.3", "@emnapi/runtime@^1.4.5": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.5.0.tgz#9aebfcb9b17195dce3ab53c86787a6b7d058db73" - integrity sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ== - dependencies: - tslib "^2.4.0" - -"@emnapi/wasi-threads@1.1.0", "@emnapi/wasi-threads@^1.0.4": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz#60b2102fddc9ccb78607e4a3cf8403ea69be41bf" - integrity sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ== - dependencies: - tslib "^2.4.0" - -"@esbuild/aix-ppc64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz#bef96351f16520055c947aba28802eede3c9e9a9" - integrity sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA== - -"@esbuild/android-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz#d2e70be7d51a529425422091e0dcb90374c1546c" - integrity sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg== - -"@esbuild/android-arm@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.9.tgz#d2a753fe2a4c73b79437d0ba1480e2d760097419" - integrity sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ== - -"@esbuild/android-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.9.tgz#5278836e3c7ae75761626962f902a0d55352e683" - integrity sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw== - -"@esbuild/darwin-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz" - integrity sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg== - -"@esbuild/darwin-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz#e27dbc3b507b3a1cea3b9280a04b8b6b725f82be" - integrity sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ== - -"@esbuild/freebsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz#364e3e5b7a1fd45d92be08c6cc5d890ca75908ca" - integrity sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q== - -"@esbuild/freebsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz#7c869b45faeb3df668e19ace07335a0711ec56ab" - integrity sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg== - -"@esbuild/linux-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz#48d42861758c940b61abea43ba9a29b186d6cb8b" - integrity sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw== - -"@esbuild/linux-arm@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz#6ce4b9cabf148274101701d112b89dc67cc52f37" - integrity sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw== - -"@esbuild/linux-ia32@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz#207e54899b79cac9c26c323fc1caa32e3143f1c4" - integrity sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A== - -"@esbuild/linux-loong64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz#0ba48a127159a8f6abb5827f21198b999ffd1fc0" - integrity sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ== - -"@esbuild/linux-mips64el@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz#a4d4cc693d185f66a6afde94f772b38ce5d64eb5" - integrity sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA== - -"@esbuild/linux-ppc64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz#0f5805c1c6d6435a1dafdc043cb07a19050357db" - integrity sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w== - -"@esbuild/linux-riscv64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz#6776edece0f8fca79f3386398b5183ff2a827547" - integrity sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg== - -"@esbuild/linux-s390x@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz#3f6f29ef036938447c2218d309dc875225861830" - integrity sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA== - -"@esbuild/linux-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz#831fe0b0e1a80a8b8391224ea2377d5520e1527f" - integrity sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg== - -"@esbuild/netbsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz#06f99d7eebe035fbbe43de01c9d7e98d2a0aa548" - integrity sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q== - -"@esbuild/netbsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz#db99858e6bed6e73911f92a88e4edd3a8c429a52" - integrity sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g== - -"@esbuild/openbsd-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz#afb886c867e36f9d86bb21e878e1185f5d5a0935" - integrity sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ== - -"@esbuild/openbsd-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz#30855c9f8381fac6a0ef5b5f31ac6e7108a66ecf" - integrity sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA== - -"@esbuild/openharmony-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz#2f2144af31e67adc2a8e3705c20c2bd97bd88314" - integrity sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg== - -"@esbuild/sunos-x64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz#69b99a9b5bd226c9eb9c6a73f990fddd497d732e" - integrity sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw== - -"@esbuild/win32-arm64@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz#d789330a712af916c88325f4ffe465f885719c6b" - integrity sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ== - -"@esbuild/win32-ia32@0.25.9": - version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz#52fc735406bd49688253e74e4e837ac2ba0789e3" - integrity sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww== - "@esbuild/win32-x64@0.25.9": version "0.25.9" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz#585624dc829cfb6e7c0aa6c3ca7d7e6daa87e34f" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz" integrity sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": @@ -368,7 +221,7 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.33.0", "@eslint/js@^9.33.0": +"@eslint/js@^9.33.0", "@eslint/js@9.33.0": version "9.33.0" resolved "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz" integrity sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A== @@ -482,15 +335,6 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@napi-rs/wasm-runtime@^0.2.12": - version "0.2.12" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" - integrity sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== - dependencies: - "@emnapi/core" "^1.4.3" - "@emnapi/runtime" "^1.4.3" - "@tybys/wasm-util" "^0.10.0" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -499,7 +343,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -740,7 +584,7 @@ aria-hidden "^1.2.4" react-remove-scroll "^2.6.3" -"@radix-ui/react-slot@1.2.3", "@radix-ui/react-slot@^1.2.3": +"@radix-ui/react-slot@^1.2.3", "@radix-ui/react-slot@1.2.3": version "1.2.3" resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz" integrity sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A== @@ -829,104 +673,9 @@ resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.32.tgz" integrity sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g== -"@rollup/rollup-android-arm-eabi@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.47.1.tgz#6e236cd2fd29bb01a300ad4ff6ed0f1a17550e69" - integrity sha512-lTahKRJip0knffA/GTNFJMrToD+CM+JJ+Qt5kjzBK/sFQ0EWqfKW3AYQSlZXN98tX0lx66083U9JYIMioMMK7g== - -"@rollup/rollup-android-arm64@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.47.1.tgz#808f2c9c7e68161add613ebcb0eac5a058a0df3c" - integrity sha512-uqxkb3RJLzlBbh/bbNQ4r7YpSZnjgMgyoEOY7Fy6GCbelkDSAzeiogxMG9TfLsBbqmGsdDObo3mzGqa8hps4MA== - -"@rollup/rollup-darwin-arm64@4.47.1": - version "4.47.1" - resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.47.1.tgz" - integrity sha512-tV6reObmxBDS4DDyLzTDIpymthNlxrLBGAoQx6m2a7eifSNEZdkXQl1PE4ZjCkEDPVgNXSzND/k9AQ3mC4IOEQ== - -"@rollup/rollup-darwin-x64@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.47.1.tgz#9aac64e886435493f2e3a0aa5e4aad098a90814c" - integrity sha512-XuJRPTnMk1lwsSnS3vYyVMu4x/+WIw1MMSiqj5C4j3QOWsMzbJEK90zG+SWV1h0B1ABGCQ0UZUjti+TQK35uHQ== - -"@rollup/rollup-freebsd-arm64@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.47.1.tgz#9fc804264f7b7a7cdad3747950299f990163be1f" - integrity sha512-79BAm8Ag/tmJ5asCqgOXsb3WY28Rdd5Lxj8ONiQzWzy9LvWORd5qVuOnjlqiWWZJw+dWewEktZb5yiM1DLLaHw== - -"@rollup/rollup-freebsd-x64@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.47.1.tgz#933feaff864feb03bbbcd0c18ea351ade957cf79" - integrity sha512-OQ2/ZDGzdOOlyfqBiip0ZX/jVFekzYrGtUsqAfLDbWy0jh1PUU18+jYp8UMpqhly5ltEqotc2miLngf9FPSWIA== - -"@rollup/rollup-linux-arm-gnueabihf@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.47.1.tgz#02915e6b2c55fe5961c27404aba2d9c8ef48ac6c" - integrity sha512-HZZBXJL1udxlCVvoVadstgiU26seKkHbbAMLg7680gAcMnRNP9SAwTMVet02ANA94kXEI2VhBnXs4e5nf7KG2A== - -"@rollup/rollup-linux-arm-musleabihf@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.47.1.tgz#1afef33191b26e76ae7f0d0dc767efc6be1285ce" - integrity sha512-sZ5p2I9UA7T950JmuZ3pgdKA6+RTBr+0FpK427ExW0t7n+QwYOcmDTK/aRlzoBrWyTpJNlS3kacgSlSTUg6P/Q== - -"@rollup/rollup-linux-arm64-gnu@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.47.1.tgz#6e7f38fb99d14143de3ce33204e6cd61e1c2c780" - integrity sha512-3hBFoqPyU89Dyf1mQRXCdpc6qC6At3LV6jbbIOZd72jcx7xNk3aAp+EjzAtN6sDlmHFzsDJN5yeUySvorWeRXA== - -"@rollup/rollup-linux-arm64-musl@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.47.1.tgz#25ab09f14bbcba85a604bcee2962d2486db90794" - integrity sha512-49J4FnMHfGodJWPw73Ve+/hsPjZgcXQGkmqBGZFvltzBKRS+cvMiWNLadOMXKGnYRhs1ToTGM0sItKISoSGUNA== - -"@rollup/rollup-linux-loongarch64-gnu@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.47.1.tgz#d3e3a3fd61e21b2753094391dee9b515a2bc9ecd" - integrity sha512-4yYU8p7AneEpQkRX03pbpLmE21z5JNys16F1BZBZg5fP9rIlb0TkeQjn5du5w4agConCCEoYIG57sNxjryHEGg== - -"@rollup/rollup-linux-ppc64-gnu@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.47.1.tgz#6b44445e2bd5866692010de241bf18d2ae8b0cb8" - integrity sha512-fAiq+J28l2YMWgC39jz/zPi2jqc0y3GSRo1yyxlBHt6UN0yYgnegHSRPa3pnHS5amT/efXQrm0ug5+aNEu9UuQ== - -"@rollup/rollup-linux-riscv64-gnu@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.47.1.tgz#3ff412d20d3b157e6aadabf84788e8c5cb221ba7" - integrity sha512-daoT0PMENNdjVYYU9xec30Y2prb1AbEIbb64sqkcQcSaR0zYuKkoPuhIztfxuqN82KYCKKrj+tQe4Gi7OSm1ow== - -"@rollup/rollup-linux-riscv64-musl@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.47.1.tgz#104f451497d53d82a49c6d08c13c59f5f30eed57" - integrity sha512-JNyXaAhWtdzfXu5pUcHAuNwGQKevR+6z/poYQKVW+pLaYOj9G1meYc57/1Xv2u4uTxfu9qEWmNTjv/H/EpAisw== - -"@rollup/rollup-linux-s390x-gnu@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.47.1.tgz#d04de7b21d181f30750760cb3553946306506172" - integrity sha512-U/CHbqKSwEQyZXjCpY43/GLYcTVKEXeRHw0rMBJP7fP3x6WpYG4LTJWR3ic6TeYKX6ZK7mrhltP4ppolyVhLVQ== - -"@rollup/rollup-linux-x64-gnu@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.47.1.tgz#a6ba88ff7480940a435b1e67ddbb3f207a7ae02f" - integrity sha512-uTLEakjxOTElfeZIGWkC34u2auLHB1AYS6wBjPGI00bWdxdLcCzK5awjs25YXpqB9lS8S0vbO0t9ZcBeNibA7g== - -"@rollup/rollup-linux-x64-musl@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.47.1.tgz#c912c8ffa0c242ed3175cd91cdeaef98109afa54" - integrity sha512-Ft+d/9DXs30BK7CHCTX11FtQGHUdpNDLJW0HHLign4lgMgBcPFN3NkdIXhC5r9iwsMwYreBBc4Rho5ieOmKNVQ== - -"@rollup/rollup-win32-arm64-msvc@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.47.1.tgz#ca5eaae89443554b461bb359112a056528cfdac0" - integrity sha512-N9X5WqGYzZnjGAFsKSfYFtAShYjwOmFJoWbLg3dYixZOZqU7hdMq+/xyS14zKLhFhZDhP9VfkzQnsdk0ZDS9IA== - -"@rollup/rollup-win32-ia32-msvc@4.47.1": - version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.47.1.tgz#34e76172515fb4b374eb990d59f54faff938246e" - integrity sha512-O+KcfeCORZADEY8oQJk4HK8wtEOCRE4MdOkb8qGZQNun3jzmj2nmhV/B/ZaaZOkPmJyvm/gW9n0gsB4eRa1eiQ== - "@rollup/rollup-win32-x64-msvc@4.47.1": version "4.47.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.47.1.tgz#e5e0a0bae2c9d4858cc9b8dc508b2e10d7f0df8b" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.47.1.tgz" integrity sha512-CpKnYa8eHthJa3c+C38v/E+/KZyF1Jdh2Cz3DyKZqEWYgrM1IHFArXNWvBLPQCKUEsAqqKX27tTqVEFbDNUcOA== "@tailwindcss/node@4.1.12": @@ -942,71 +691,9 @@ source-map-js "^1.2.1" tailwindcss "4.1.12" -"@tailwindcss/oxide-android-arm64@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.12.tgz#27920fe61fa2743afe8a8ca296fa640b609d17d5" - integrity sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ== - -"@tailwindcss/oxide-darwin-arm64@4.1.12": - version "4.1.12" - resolved "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.12.tgz" - integrity sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw== - -"@tailwindcss/oxide-darwin-x64@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.12.tgz#8ddb7e5ddfd9b049ec84a2bda99f2b04a86859f5" - integrity sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg== - -"@tailwindcss/oxide-freebsd-x64@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.12.tgz#da1c0b16b7a5f95a1e400f299a3ec94fb6fd40ac" - integrity sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww== - -"@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.12.tgz#34e558aa6e869c6fe9867cb78ed7ba651b9fcaa4" - integrity sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ== - -"@tailwindcss/oxide-linux-arm64-gnu@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.12.tgz#0a00a8146ab6215f81b2d385056c991441bf390e" - integrity sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g== - -"@tailwindcss/oxide-linux-arm64-musl@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.12.tgz#b138f494068884ae0d8c343dc1904b22f5e98dc6" - integrity sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA== - -"@tailwindcss/oxide-linux-x64-gnu@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.12.tgz#5b9d5f23b15cdb714639f5b9741c0df5d610f794" - integrity sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q== - -"@tailwindcss/oxide-linux-x64-musl@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.12.tgz#f68ec530d3ca6875ea9015bcd5dd0762ee5e2f5d" - integrity sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A== - -"@tailwindcss/oxide-wasm32-wasi@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.12.tgz#9fd15a1ebde6076c42c445c5e305c31673ead965" - integrity sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg== - dependencies: - "@emnapi/core" "^1.4.5" - "@emnapi/runtime" "^1.4.5" - "@emnapi/wasi-threads" "^1.0.4" - "@napi-rs/wasm-runtime" "^0.2.12" - "@tybys/wasm-util" "^0.10.0" - tslib "^2.8.0" - -"@tailwindcss/oxide-win32-arm64-msvc@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.12.tgz#938bcc6a82e1120ea4fe2ce94be0a8cdf3ae92c7" - integrity sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg== - "@tailwindcss/oxide-win32-x64-msvc@4.1.12": version "4.1.12" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.12.tgz#b1ee2ed0ef2c4095ddec3684a1987e2b3613af36" + resolved "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.12.tgz" integrity sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA== "@tailwindcss/oxide@4.1.12": @@ -1039,13 +726,6 @@ "@tailwindcss/oxide" "4.1.12" tailwindcss "4.1.12" -"@tybys/wasm-util@^0.10.0": - version "0.10.0" - resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.0.tgz#2fd3cd754b94b378734ce17058d0507c45c88369" - integrity sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ== - dependencies: - tslib "^2.4.0" - "@types/babel__core@^7.20.5": version "7.20.5" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" @@ -1118,7 +798,7 @@ "@types/d3-interpolate" "*" "@types/d3-selection" "*" -"@types/estree@1.0.8", "@types/estree@^1.0.6": +"@types/estree@^1.0.6", "@types/estree@1.0.8": version "1.0.8" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== @@ -1128,19 +808,19 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/node@^24.3.0": +"@types/node@^20.19.0 || >=22.12.0", "@types/node@^24.3.0": version "24.3.0" resolved "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz" integrity sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow== dependencies: undici-types "~7.10.0" -"@types/react-dom@^19.1.7": +"@types/react-dom@*", "@types/react-dom@^19.1.7": version "19.1.7" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz" integrity sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw== -"@types/react@^19.1.10": +"@types/react@*", "@types/react@^19.0.0", "@types/react@^19.1.10", "@types/react@>=16.8", "@types/react@>=18.0.0": version "19.1.10" resolved "https://registry.npmjs.org/@types/react/-/react-19.1.10.tgz" integrity sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg== @@ -1162,7 +842,7 @@ natural-compare "^1.4.0" ts-api-utils "^2.1.0" -"@typescript-eslint/parser@8.40.0": +"@typescript-eslint/parser@^8.40.0", "@typescript-eslint/parser@8.40.0": version "8.40.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.40.0.tgz" integrity sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw== @@ -1190,7 +870,7 @@ "@typescript-eslint/types" "8.40.0" "@typescript-eslint/visitor-keys" "8.40.0" -"@typescript-eslint/tsconfig-utils@8.40.0", "@typescript-eslint/tsconfig-utils@^8.40.0": +"@typescript-eslint/tsconfig-utils@^8.40.0", "@typescript-eslint/tsconfig-utils@8.40.0": version "8.40.0" resolved "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.40.0.tgz" integrity sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw== @@ -1206,7 +886,7 @@ debug "^4.3.4" ts-api-utils "^2.1.0" -"@typescript-eslint/types@8.40.0", "@typescript-eslint/types@^8.40.0": +"@typescript-eslint/types@^8.40.0", "@typescript-eslint/types@8.40.0": version "8.40.0" resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.40.0.tgz" integrity sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg== @@ -1259,7 +939,7 @@ "@xyflow/react@^12.8.4": version "12.8.4" - resolved "https://registry.yarnpkg.com/@xyflow/react/-/react-12.8.4.tgz#db0eabd9e356c25f5ebf427413a8c5dd46113394" + resolved "https://registry.npmjs.org/@xyflow/react/-/react-12.8.4.tgz" integrity sha512-bqUu4T5QSHiCFPkoH+b+LROKwQJdLvcjhGbNW9c1dLafCBRjmH1IYz0zPE+lRDXCtQ9kRyFxz3tG19+8VORJ1w== dependencies: "@xyflow/system" "0.0.68" @@ -1286,7 +966,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.15.0: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.15.0: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -1347,7 +1027,7 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.24.0: +browserslist@^4.24.0, "browserslist@>= 4.21.0": version "4.25.3" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.25.3.tgz" integrity sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ== @@ -1443,7 +1123,7 @@ csstype@^3.0.2: resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== -"d3-drag@2 - 3", d3-drag@^3.0.0: +d3-drag@^3.0.0, "d3-drag@2 - 3": version "3.0.0" resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== @@ -1456,14 +1136,14 @@ csstype@^3.0.2: resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== -"d3-interpolate@1 - 3", d3-interpolate@^3.0.1: +d3-interpolate@^3.0.1, "d3-interpolate@1 - 3": version "3.0.1" resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== dependencies: d3-color "1 - 3" -"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: +d3-selection@^3.0.0, "d3-selection@2 - 3", d3-selection@3: version "3.0.0" resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== @@ -1600,7 +1280,7 @@ eslint-visitor-keys@^4.2.1: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -eslint@^9.33.0: +"eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^9.33.0, eslint@>=8.40: version "9.33.0" resolved "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz" integrity sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA== @@ -1846,7 +1526,7 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -jiti@^2.5.1: +jiti@*, jiti@^2.5.1, jiti@>=1.21.0: version "2.5.1" resolved "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz" integrity sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w== @@ -1903,57 +1583,12 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -lightningcss-darwin-arm64@1.30.1: - version "1.30.1" - resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz" - integrity sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ== - -lightningcss-darwin-x64@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz#e81105d3fd6330860c15fe860f64d39cff5fbd22" - integrity sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA== - -lightningcss-freebsd-x64@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz#a0e732031083ff9d625c5db021d09eb085af8be4" - integrity sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig== - -lightningcss-linux-arm-gnueabihf@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz#1f5ecca6095528ddb649f9304ba2560c72474908" - integrity sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q== - -lightningcss-linux-arm64-gnu@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz#eee7799726103bffff1e88993df726f6911ec009" - integrity sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw== - -lightningcss-linux-arm64-musl@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz#f2e4b53f42892feeef8f620cbb889f7c064a7dfe" - integrity sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ== - -lightningcss-linux-x64-gnu@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz#2fc7096224bc000ebb97eea94aea248c5b0eb157" - integrity sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw== - -lightningcss-linux-x64-musl@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz#66dca2b159fd819ea832c44895d07e5b31d75f26" - integrity sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ== - -lightningcss-win32-arm64-msvc@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz#7d8110a19d7c2d22bfdf2f2bb8be68e7d1b69039" - integrity sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA== - lightningcss-win32-x64-msvc@1.30.1: version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz#fd7dd008ea98494b85d24b4bea016793f2e0e352" + resolved "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz" integrity sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg== -lightningcss@1.30.1: +lightningcss@^1.21.0, lightningcss@1.30.1: version "1.30.1" resolved "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz" integrity sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg== @@ -2063,7 +1698,7 @@ natural-compare@^1.4.0: next-themes@^0.4.6: version "0.4.6" - resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.4.6.tgz#8d7e92d03b8fea6582892a50a928c9b23502e8b6" + resolved "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz" integrity sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA== node-releases@^2.0.19: @@ -2124,7 +1759,7 @@ picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^4.0.3: +"picomatch@^3 || ^4", picomatch@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== @@ -2153,7 +1788,7 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -react-dom@^19.1.1: +"react-dom@^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", react-dom@^19.1.1, react-dom@>=16.8.0, react-dom@>=17: version "19.1.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz" integrity sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw== @@ -2192,7 +1827,7 @@ react-style-singleton@^2.2.2, react-style-singleton@^2.2.3: get-nonce "^1.0.0" tslib "^2.0.0" -react@^19.1.1: +"react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", react@^19.1.1, react@>=16.8, react@>=16.8.0, react@>=17, react@>=18.0.0: version "19.1.1" resolved "https://registry.npmjs.org/react/-/react-19.1.1.tgz" integrity sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ== @@ -2292,7 +1927,7 @@ tailwind-merge@^3.3.1: resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz" integrity sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g== -tailwindcss@4.1.12, tailwindcss@^4.1.12: +tailwindcss@^4.1.12, tailwindcss@4.1.12: version "4.1.12" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz" integrity sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA== @@ -2316,7 +1951,7 @@ tar@^7.4.3: tinyglobby@^0.2.15: version "0.2.15" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" + resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz" integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== dependencies: fdir "^6.5.0" @@ -2334,7 +1969,7 @@ ts-api-utils@^2.1.0: resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz" integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== -tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.0: +tslib@^2.0.0, tslib@^2.1.0: version "2.8.1" resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -2361,7 +1996,7 @@ typescript-eslint@^8.39.1: "@typescript-eslint/typescript-estree" "8.40.0" "@typescript-eslint/utils" "8.40.0" -typescript@~5.8.3: +typescript@>=4.8.4, "typescript@>=4.8.4 <6.0.0", typescript@~5.8.3: version "5.8.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz" integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== @@ -2401,15 +2036,15 @@ use-sidecar@^1.1.3: detect-node-es "^1.1.0" tslib "^2.0.0" -use-sync-external-store@^1.2.2: +use-sync-external-store@^1.2.2, use-sync-external-store@>=1.2.0: version "1.5.0" resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz" integrity sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A== -vite@^7.1.11: - version "7.1.11" - resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.11.tgz#4d006746112fee056df64985191e846ebfb6007e" - integrity sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg== +"vite@^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "vite@^5.2.0 || ^6 || ^7", vite@^7.1.11: + version "7.1.12" + resolved "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz" + integrity sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug== dependencies: esbuild "^0.25.0" fdir "^6.5.0" @@ -2456,5 +2091,5 @@ zustand@^4.4.0: zustand@^5.0.8: version "5.0.8" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.8.tgz#b998a0c088c7027a20f2709141a91cb07ac57f8a" + resolved "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz" integrity sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==