diff --git a/.editorconfig b/.editorconfig index d758f546..9ab79340 100644 --- a/.editorconfig +++ b/.editorconfig @@ -31,6 +31,9 @@ csharp_new_line_before_finally = true csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_anonymous_types = true +# Limit consecutive empty lines (not always respected everywhere) +csharp_style_allow_multiple_blank_lines_experimental = false + dotnet_diagnostic.IDE0290.severity = none dotnet_diagnostic.IDE0305.severity = none diff --git a/src/Abstractions/CrestApps.Core.AI.Abstractions/Clients/IAIClientProvider.cs b/src/Abstractions/CrestApps.Core.AI.Abstractions/Clients/IAIClientProvider.cs index 4ed5ad73..e360fa50 100644 --- a/src/Abstractions/CrestApps.Core.AI.Abstractions/Clients/IAIClientProvider.cs +++ b/src/Abstractions/CrestApps.Core.AI.Abstractions/Clients/IAIClientProvider.cs @@ -70,4 +70,4 @@ public interface IAIClientProvider /// The optional deployment name to use. /// An array of available instances. Task GetSpeechVoicesAsync(AIProviderConnectionEntry connection, string deploymentName = null); -} \ No newline at end of file +} diff --git a/src/Abstractions/CrestApps.Core.AI.Abstractions/Models/AIDeploymentTypeExtensions.cs b/src/Abstractions/CrestApps.Core.AI.Abstractions/Models/AIDeploymentTypeExtensions.cs index e36062be..29b9a49e 100644 --- a/src/Abstractions/CrestApps.Core.AI.Abstractions/Models/AIDeploymentTypeExtensions.cs +++ b/src/Abstractions/CrestApps.Core.AI.Abstractions/Models/AIDeploymentTypeExtensions.cs @@ -17,4 +17,4 @@ public static IEnumerable GetSupportedTypes(this AIDeploymentT { return Enum.GetValues().Where(type => value.Supports(type)); } -} \ No newline at end of file +} diff --git a/src/Abstractions/CrestApps.Core.AI.Abstractions/Orchestration/AIInvocationContext.cs b/src/Abstractions/CrestApps.Core.AI.Abstractions/Orchestration/AIInvocationContext.cs index 56f95137..d10e8359 100644 --- a/src/Abstractions/CrestApps.Core.AI.Abstractions/Orchestration/AIInvocationContext.cs +++ b/src/Abstractions/CrestApps.Core.AI.Abstractions/Orchestration/AIInvocationContext.cs @@ -75,4 +75,4 @@ public int NextReferenceIndex() { return Interlocked.Increment(ref _referenceIndex); } -} \ No newline at end of file +} diff --git a/src/Abstractions/CrestApps.Core.AI.Abstractions/Orchestration/AIInvocationScope.cs b/src/Abstractions/CrestApps.Core.AI.Abstractions/Orchestration/AIInvocationScope.cs index 10b5a5b6..023a5e9f 100644 --- a/src/Abstractions/CrestApps.Core.AI.Abstractions/Orchestration/AIInvocationScope.cs +++ b/src/Abstractions/CrestApps.Core.AI.Abstractions/Orchestration/AIInvocationScope.cs @@ -81,4 +81,4 @@ public void Dispose() _current.Value = null; } } -} \ No newline at end of file +} diff --git a/src/Abstractions/CrestApps.Core.AI.Abstractions/Profiles/IAIProfileManager.cs b/src/Abstractions/CrestApps.Core.AI.Abstractions/Profiles/IAIProfileManager.cs index ea149e9a..1343fec3 100644 --- a/src/Abstractions/CrestApps.Core.AI.Abstractions/Profiles/IAIProfileManager.cs +++ b/src/Abstractions/CrestApps.Core.AI.Abstractions/Profiles/IAIProfileManager.cs @@ -1,18 +1,19 @@ -using CrestApps.Core.AI.Models; -using CrestApps.Core.Services; - -namespace CrestApps.Core.AI.Profiles; -/// -/// Manages AI profiles with CRUD operations, name-based lookup, -/// and type-filtered retrieval. AI profiles define chat, agent, and embedding -/// configurations that drive AI completion behavior. -/// -public interface IAIProfileManager : INamedCatalogManager -{ - /// - /// Asynchronously retrieves a collection of AI chat profiles of the specified type. - /// - /// The type of AI chat profiles to retrieve. - /// A ValueTask that represents the asynchronous operation. The result is an enumerable collection of AIProfile objects matching the specified type. - ValueTask> GetAsync(AIProfileType type); -} +using CrestApps.Core.AI.Models; +using CrestApps.Core.Services; + +namespace CrestApps.Core.AI.Profiles; + +/// +/// Manages AI profiles with CRUD operations, name-based lookup, +/// and type-filtered retrieval. AI profiles define chat, agent, and embedding +/// configurations that drive AI completion behavior. +/// +public interface IAIProfileManager : INamedCatalogManager +{ + /// + /// Asynchronously retrieves a collection of AI chat profiles of the specified type. + /// + /// The type of AI chat profiles to retrieve. + /// A ValueTask that represents the asynchronous operation. The result is an enumerable collection of AIProfile objects matching the specified type. + ValueTask> GetAsync(AIProfileType type); +} diff --git a/src/Abstractions/CrestApps.Core.AI.Abstractions/Profiles/IAIProfileStore.cs b/src/Abstractions/CrestApps.Core.AI.Abstractions/Profiles/IAIProfileStore.cs index 0c407ff3..48b1de35 100644 --- a/src/Abstractions/CrestApps.Core.AI.Abstractions/Profiles/IAIProfileStore.cs +++ b/src/Abstractions/CrestApps.Core.AI.Abstractions/Profiles/IAIProfileStore.cs @@ -1,20 +1,22 @@ -using CrestApps.Core.AI.Models; -using CrestApps.Core.Services; -namespace CrestApps.Core.AI.Profiles; -/// -/// Provides persistent storage for AI profiles, supporting CRUD operations, -/// name-based lookup, and efficient type-filtered queries via index. -/// -public interface IAIProfileStore : INamedCatalog -{ - /// - /// Asynchronously retrieves a collection of AI profiles of the specified type - /// using an efficient index query rather than loading all profiles. - /// - /// The type of AI profiles to retrieve. - /// - /// A representing the asynchronous operation. - /// The result is a read-only collection of matching the specified type. - /// - ValueTask> GetByTypeAsync(AIProfileType type); -} +using CrestApps.Core.AI.Models; +using CrestApps.Core.Services; + +namespace CrestApps.Core.AI.Profiles; + +/// +/// Provides persistent storage for AI profiles, supporting CRUD operations, +/// name-based lookup, and efficient type-filtered queries via index. +/// +public interface IAIProfileStore : INamedCatalog +{ + /// + /// Asynchronously retrieves a collection of AI profiles of the specified type + /// using an efficient index query rather than loading all profiles. + /// + /// The type of AI profiles to retrieve. + /// + /// A representing the asynchronous operation. + /// The result is a read-only collection of matching the specified type. + /// + ValueTask> GetByTypeAsync(AIProfileType type); +} diff --git a/src/Abstractions/CrestApps.Core.AI.Abstractions/ResponseHandling/ChatResponseHandlerResult.cs b/src/Abstractions/CrestApps.Core.AI.Abstractions/ResponseHandling/ChatResponseHandlerResult.cs index 2a1a6737..3baffb15 100644 --- a/src/Abstractions/CrestApps.Core.AI.Abstractions/ResponseHandling/ChatResponseHandlerResult.cs +++ b/src/Abstractions/CrestApps.Core.AI.Abstractions/ResponseHandling/ChatResponseHandlerResult.cs @@ -46,4 +46,4 @@ public static ChatResponseHandlerResult Streaming(IAsyncEnumerable queryTokens, HashSet InvokeCoreAsync(AIFunctionArguments a return "An error occurred while searching for tools."; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.A2A/Functions/ListAvailableAgentsFunction.cs b/src/Primitives/CrestApps.Core.AI.A2A/Functions/ListAvailableAgentsFunction.cs index 3d28ef95..64c736aa 100644 --- a/src/Primitives/CrestApps.Core.AI.A2A/Functions/ListAvailableAgentsFunction.cs +++ b/src/Primitives/CrestApps.Core.AI.A2A/Functions/ListAvailableAgentsFunction.cs @@ -100,4 +100,4 @@ protected override async ValueTask InvokeCoreAsync(AIFunctionArguments a return agents.Count > 0 ? JsonSerializer.Serialize(agents) : "No agents are currently available."; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.A2A/Handlers/A2AAICompletionContextBuilderHandler.cs b/src/Primitives/CrestApps.Core.AI.A2A/Handlers/A2AAICompletionContextBuilderHandler.cs index ab4f6047..fe25bb68 100644 --- a/src/Primitives/CrestApps.Core.AI.A2A/Handlers/A2AAICompletionContextBuilderHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.A2A/Handlers/A2AAICompletionContextBuilderHandler.cs @@ -20,4 +20,4 @@ public Task BuiltAsync(AICompletionContextBuiltContext context) { return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.A2A/Services/DefaultA2AAgentCardCacheService.cs b/src/Primitives/CrestApps.Core.AI.A2A/Services/DefaultA2AAgentCardCacheService.cs index ff40fd17..f7496a49 100644 --- a/src/Primitives/CrestApps.Core.AI.A2A/Services/DefaultA2AAgentCardCacheService.cs +++ b/src/Primitives/CrestApps.Core.AI.A2A/Services/DefaultA2AAgentCardCacheService.cs @@ -70,4 +70,4 @@ private static string GetCacheKey(string connectionId) { return $"A2AAgentCard:{connectionId}"; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.A2A/Services/DefaultA2AConnectionAuthService.cs b/src/Primitives/CrestApps.Core.AI.A2A/Services/DefaultA2AConnectionAuthService.cs index e0f33fdf..cf6c10e6 100644 --- a/src/Primitives/CrestApps.Core.AI.A2A/Services/DefaultA2AConnectionAuthService.cs +++ b/src/Primitives/CrestApps.Core.AI.A2A/Services/DefaultA2AConnectionAuthService.cs @@ -306,4 +306,4 @@ private sealed class OAuth2TokenResponse [JsonPropertyName("expires_in")] public int ExpiresIn { get; set; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.AzureAIInference/Services/AzureAIInferenceClientProvider.cs b/src/Primitives/CrestApps.Core.AI.AzureAIInference/Services/AzureAIInferenceClientProvider.cs index 41627891..1039aff6 100644 --- a/src/Primitives/CrestApps.Core.AI.AzureAIInference/Services/AzureAIInferenceClientProvider.cs +++ b/src/Primitives/CrestApps.Core.AI.AzureAIInference/Services/AzureAIInferenceClientProvider.cs @@ -64,4 +64,4 @@ protected override ISpeechToTextClient GetSpeechToTextClient(AIProviderConnectio { throw new NotSupportedException("Azure AI Inference does not currently support speech-to-text functionality."); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.AzureAIInference/Services/AzureAIInferenceCompletionClient.cs b/src/Primitives/CrestApps.Core.AI.AzureAIInference/Services/AzureAIInferenceCompletionClient.cs index 60ca255a..a2a3f7e2 100644 --- a/src/Primitives/CrestApps.Core.AI.AzureAIInference/Services/AzureAIInferenceCompletionClient.cs +++ b/src/Primitives/CrestApps.Core.AI.AzureAIInference/Services/AzureAIInferenceCompletionClient.cs @@ -23,4 +23,4 @@ protected override string ProviderName return AzureAIInferenceConstants.ProviderName; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Chat/Handlers/ChatInteractionCompletionContextBuilderHandler.cs b/src/Primitives/CrestApps.Core.AI.Chat/Handlers/ChatInteractionCompletionContextBuilderHandler.cs index a9e930a7..0bbf8968 100644 --- a/src/Primitives/CrestApps.Core.AI.Chat/Handlers/ChatInteractionCompletionContextBuilderHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.Chat/Handlers/ChatInteractionCompletionContextBuilderHandler.cs @@ -82,4 +82,4 @@ private async Task ResolveSystemMessageAsync(ChatInteraction interaction return parts.Count == 0 ? null : string.Join(Environment.NewLine + Environment.NewLine, parts); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Chat/Handlers/DataSourceChatInteractionSettingsHandler.cs b/src/Primitives/CrestApps.Core.AI.Chat/Handlers/DataSourceChatInteractionSettingsHandler.cs index 1ea7e34d..da7e8a51 100644 --- a/src/Primitives/CrestApps.Core.AI.Chat/Handlers/DataSourceChatInteractionSettingsHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.Chat/Handlers/DataSourceChatInteractionSettingsHandler.cs @@ -128,4 +128,4 @@ private static string GetString(JsonElement element, string propertyName) return null; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Chat/Handlers/ExtractedDataOrchestrationHandler.cs b/src/Primitives/CrestApps.Core.AI.Chat/Handlers/ExtractedDataOrchestrationHandler.cs index d41cc4a6..3e2fa9d3 100644 --- a/src/Primitives/CrestApps.Core.AI.Chat/Handlers/ExtractedDataOrchestrationHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.Chat/Handlers/ExtractedDataOrchestrationHandler.cs @@ -50,4 +50,4 @@ public async Task BuiltAsync(OrchestrationContextBuiltContext context) _logger.LogDebug("Injected extracted session state for AIProfile '{ProfileId}' with {CollectedCount} collected field(s) and {MissingCount} missing field(s).", profile.ItemId, collectedFields.Count, missingFields.Count); } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Chat/Handlers/PromptTemplateChatInteractionSettingsHandler.cs b/src/Primitives/CrestApps.Core.AI.Chat/Handlers/PromptTemplateChatInteractionSettingsHandler.cs index 6645553f..f82e1a3f 100644 --- a/src/Primitives/CrestApps.Core.AI.Chat/Handlers/PromptTemplateChatInteractionSettingsHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.Chat/Handlers/PromptTemplateChatInteractionSettingsHandler.cs @@ -80,4 +80,4 @@ private static string GetString(JsonElement element, string propertyName) return null; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Claude/Handlers/ClaudeChatInteractionSettingsHandler.cs b/src/Primitives/CrestApps.Core.AI.Claude/Handlers/ClaudeChatInteractionSettingsHandler.cs index 690b0bc9..3dade02f 100644 --- a/src/Primitives/CrestApps.Core.AI.Claude/Handlers/ClaudeChatInteractionSettingsHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.Claude/Handlers/ClaudeChatInteractionSettingsHandler.cs @@ -1,6 +1,6 @@ using System.Text.Json; -using CrestApps.Core.AI.Claude.Models; using CrestApps.Core.AI.Chat; +using CrestApps.Core.AI.Claude.Models; using CrestApps.Core.AI.Models; namespace CrestApps.Core.AI.Claude.Handlers; diff --git a/src/Primitives/CrestApps.Core.AI.Claude/ServiceCollectionExtensions.cs b/src/Primitives/CrestApps.Core.AI.Claude/ServiceCollectionExtensions.cs index d736d3c4..fb026d16 100644 --- a/src/Primitives/CrestApps.Core.AI.Claude/ServiceCollectionExtensions.cs +++ b/src/Primitives/CrestApps.Core.AI.Claude/ServiceCollectionExtensions.cs @@ -1,6 +1,6 @@ +using CrestApps.Core.AI.Chat; using CrestApps.Core.AI.Claude.Handlers; using CrestApps.Core.AI.Claude.Services; -using CrestApps.Core.AI.Chat; using CrestApps.Core.AI.Orchestration; using CrestApps.Core.Builders; using Microsoft.Extensions.DependencyInjection; diff --git a/src/Primitives/CrestApps.Core.AI.Copilot/Handlers/CopilotChatInteractionSettingsHandler.cs b/src/Primitives/CrestApps.Core.AI.Copilot/Handlers/CopilotChatInteractionSettingsHandler.cs index a2d5e6be..acd7c2b1 100644 --- a/src/Primitives/CrestApps.Core.AI.Copilot/Handlers/CopilotChatInteractionSettingsHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.Copilot/Handlers/CopilotChatInteractionSettingsHandler.cs @@ -62,4 +62,4 @@ private static bool GetBool(JsonElement element, string propertyName) return false; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Copilot/Handlers/CopilotOrchestrationContextHandler.cs b/src/Primitives/CrestApps.Core.AI.Copilot/Handlers/CopilotOrchestrationContextHandler.cs index a6903872..d149890b 100644 --- a/src/Primitives/CrestApps.Core.AI.Copilot/Handlers/CopilotOrchestrationContextHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.Copilot/Handlers/CopilotOrchestrationContextHandler.cs @@ -29,4 +29,4 @@ public Task BuiltAsync(OrchestrationContextBuiltContext context) { return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Copilot/Services/CopilotOrchestrator.cs b/src/Primitives/CrestApps.Core.AI.Copilot/Services/CopilotOrchestrator.cs index 332c300c..a39a8ca6 100644 --- a/src/Primitives/CrestApps.Core.AI.Copilot/Services/CopilotOrchestrator.cs +++ b/src/Primitives/CrestApps.Core.AI.Copilot/Services/CopilotOrchestrator.cs @@ -576,4 +576,4 @@ private static ChatResponseUpdate CreateTextResponse(string responseText) Contents = [new TextContent(responseText)], }; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Markdown/Services/MarkdownAITextNormalizer.cs b/src/Primitives/CrestApps.Core.AI.Markdown/Services/MarkdownAITextNormalizer.cs index 3a203120..5c1dcfc0 100644 --- a/src/Primitives/CrestApps.Core.AI.Markdown/Services/MarkdownAITextNormalizer.cs +++ b/src/Primitives/CrestApps.Core.AI.Markdown/Services/MarkdownAITextNormalizer.cs @@ -20,4 +20,4 @@ public string NormalizeTitle(string title) { return RagTextNormalizer.NormalizeTitle(title); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Markdown/Services/RagTextNormalizer.cs b/src/Primitives/CrestApps.Core.AI.Markdown/Services/RagTextNormalizer.cs index bc176633..9e9c4d84 100644 --- a/src/Primitives/CrestApps.Core.AI.Markdown/Services/RagTextNormalizer.cs +++ b/src/Primitives/CrestApps.Core.AI.Markdown/Services/RagTextNormalizer.cs @@ -105,4 +105,4 @@ private static string NormalizeContentWhitespace(string text) private static partial Regex MultipleNewlinesRegex(); [GeneratedRegex(@"\s+")] private static partial Regex AllWhitespaceRegex(); -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Mcp/Handlers/McpAICompletionContextBuilderHandler.cs b/src/Primitives/CrestApps.Core.AI.Mcp/Handlers/McpAICompletionContextBuilderHandler.cs index b8af7280..169eda0f 100644 --- a/src/Primitives/CrestApps.Core.AI.Mcp/Handlers/McpAICompletionContextBuilderHandler.cs +++ b/src/Primitives/CrestApps.Core.AI.Mcp/Handlers/McpAICompletionContextBuilderHandler.cs @@ -20,4 +20,4 @@ public Task BuiltAsync(AICompletionContextBuiltContext context) { return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Mcp/Models/McpClientAIOptions.cs b/src/Primitives/CrestApps.Core.AI.Mcp/Models/McpClientAIOptions.cs index 4d1e9a32..399070e7 100644 --- a/src/Primitives/CrestApps.Core.AI.Mcp/Models/McpClientAIOptions.cs +++ b/src/Primitives/CrestApps.Core.AI.Mcp/Models/McpClientAIOptions.cs @@ -45,4 +45,4 @@ public McpClientTransportEntry(string type) public string Type { get; private set; } public LocalizedString DisplayName { get; set; } public LocalizedString Description { get; set; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Mcp/Models/McpOptions.cs b/src/Primitives/CrestApps.Core.AI.Mcp/Models/McpOptions.cs index 609e3e11..66b0d67d 100644 --- a/src/Primitives/CrestApps.Core.AI.Mcp/Models/McpOptions.cs +++ b/src/Primitives/CrestApps.Core.AI.Mcp/Models/McpOptions.cs @@ -50,4 +50,4 @@ public McpResourceTypeEntry(string type) /// These are displayed in the UI to help users understand what variables can be used in URI patterns. /// public McpResourceVariable[] SupportedVariables { get; set; } = []; -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Mcp/Services/DefaultOAuth2TokenService.cs b/src/Primitives/CrestApps.Core.AI.Mcp/Services/DefaultOAuth2TokenService.cs index d44af760..0ef529f4 100644 --- a/src/Primitives/CrestApps.Core.AI.Mcp/Services/DefaultOAuth2TokenService.cs +++ b/src/Primitives/CrestApps.Core.AI.Mcp/Services/DefaultOAuth2TokenService.cs @@ -185,4 +185,4 @@ private sealed class OAuth2TokenResponse [System.Text.Json.Serialization.JsonPropertyName("expires_in")] public int ExpiresIn { get; set; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Mcp/Services/SseClientTransportProvider.cs b/src/Primitives/CrestApps.Core.AI.Mcp/Services/SseClientTransportProvider.cs index b654471a..92544852 100644 --- a/src/Primitives/CrestApps.Core.AI.Mcp/Services/SseClientTransportProvider.cs +++ b/src/Primitives/CrestApps.Core.AI.Mcp/Services/SseClientTransportProvider.cs @@ -114,4 +114,4 @@ private string Unprotect(IDataProtector protector, string value) return value; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Mcp/Services/StdioClientTransportProvider.cs b/src/Primitives/CrestApps.Core.AI.Mcp/Services/StdioClientTransportProvider.cs index 626f030a..8fb9d9cc 100644 --- a/src/Primitives/CrestApps.Core.AI.Mcp/Services/StdioClientTransportProvider.cs +++ b/src/Primitives/CrestApps.Core.AI.Mcp/Services/StdioClientTransportProvider.cs @@ -21,4 +21,4 @@ public Task GetAsync(McpConnection connection) return Task.FromResult(transport); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Ollama/Services/OllamaAIClientProvider.cs b/src/Primitives/CrestApps.Core.AI.Ollama/Services/OllamaAIClientProvider.cs index 45187c72..1150ce5f 100644 --- a/src/Primitives/CrestApps.Core.AI.Ollama/Services/OllamaAIClientProvider.cs +++ b/src/Primitives/CrestApps.Core.AI.Ollama/Services/OllamaAIClientProvider.cs @@ -42,4 +42,4 @@ protected override ISpeechToTextClient GetSpeechToTextClient(AIProviderConnectio { throw new NotSupportedException("Ollama does not currently support speech-to-text functionality."); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.Ollama/Services/OllamaCompletionClient.cs b/src/Primitives/CrestApps.Core.AI.Ollama/Services/OllamaCompletionClient.cs index 42e39684..c43bbfb7 100644 --- a/src/Primitives/CrestApps.Core.AI.Ollama/Services/OllamaCompletionClient.cs +++ b/src/Primitives/CrestApps.Core.AI.Ollama/Services/OllamaCompletionClient.cs @@ -23,4 +23,4 @@ protected override string ProviderName return OllamaConstants.ProviderName; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureOpenAIClientProvider.cs b/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureOpenAIClientProvider.cs index 8752557d..d42c2e5d 100644 --- a/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureOpenAIClientProvider.cs +++ b/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureOpenAIClientProvider.cs @@ -74,4 +74,4 @@ private AzureOpenAIClient GetClient(AIProviderConnectionEntry connection, Uri en }; return azureClient; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureOpenAICompletionClient.cs b/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureOpenAICompletionClient.cs index 4dd70c76..ef37a502 100644 --- a/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureOpenAICompletionClient.cs +++ b/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureOpenAICompletionClient.cs @@ -515,4 +515,4 @@ private async Task RecordUsageAsync(AICompletionContext context, string connecti var record = AICompletionUsageRecordFactory.Create(context, AzureOpenAIConstants.ClientName, Name, connectionName, deploymentName, modelName, responseId, usage?.InputTokenCount ?? 0, usage?.OutputTokenCount ?? 0, usage?.TotalTokenCount ?? 0, responseLatencyMs, isStreaming); await observers.InvokeHandlersAsync((observer, usageRecord) => observer.UsageRecordedAsync(usageRecord, cancellationToken), record, _logger); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureSpeechClientProvider.cs b/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureSpeechClientProvider.cs index 6a0efa0c..a5dc023d 100644 --- a/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureSpeechClientProvider.cs +++ b/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureSpeechClientProvider.cs @@ -81,4 +81,4 @@ private static (Uri endpoint, AzureAuthenticationType authType, string apiKey, s var identityId = connection.GetIdentityId(); return (endpoint, authType, apiKey, identityId); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureSpeechServiceSpeechToTextClient.cs b/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureSpeechServiceSpeechToTextClient.cs index d1664dcf..b8a8adf0 100644 --- a/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureSpeechServiceSpeechToTextClient.cs +++ b/src/Primitives/CrestApps.Core.AI.OpenAI.Azure/Services/AzureSpeechServiceSpeechToTextClient.cs @@ -558,4 +558,4 @@ private static bool IsGStreamerError(ApplicationException ex) { return ex.Message.Contains("0x29", StringComparison.OrdinalIgnoreCase) || ex.Message.Contains("GSTREAMER", StringComparison.OrdinalIgnoreCase); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.OpenAI/Services/OpenAIClientProvider.cs b/src/Primitives/CrestApps.Core.AI.OpenAI/Services/OpenAIClientProvider.cs index 85e1427a..e45e356f 100644 --- a/src/Primitives/CrestApps.Core.AI.OpenAI/Services/OpenAIClientProvider.cs +++ b/src/Primitives/CrestApps.Core.AI.OpenAI/Services/OpenAIClientProvider.cs @@ -68,4 +68,4 @@ private static OpenAIClient GetOpenAIClient(AIProviderConnectionEntry connection return new OpenAIClient(new ApiKeyCredential(connection.GetApiKey()), new OpenAIClientOptions { Endpoint = endpoint, }); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI.OpenAI/Services/OpenAICompletionClient.cs b/src/Primitives/CrestApps.Core.AI.OpenAI/Services/OpenAICompletionClient.cs index b8d75271..50002469 100644 --- a/src/Primitives/CrestApps.Core.AI.OpenAI/Services/OpenAICompletionClient.cs +++ b/src/Primitives/CrestApps.Core.AI.OpenAI/Services/OpenAICompletionClient.cs @@ -23,4 +23,4 @@ protected override string ProviderName return OpenAIConstants.ProviderName; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/AIOptions.cs b/src/Primitives/CrestApps.Core.AI/AIOptions.cs index 5da3535d..70e26aa1 100644 --- a/src/Primitives/CrestApps.Core.AI/AIOptions.cs +++ b/src/Primitives/CrestApps.Core.AI/AIOptions.cs @@ -140,4 +140,4 @@ public void AddTemplateSource(string name, Action configu _templateSources[name] = entry; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Extensions/AIFunctionArgumentsExtensions.cs b/src/Primitives/CrestApps.Core.AI/Extensions/AIFunctionArgumentsExtensions.cs index b16f92d5..962469d5 100644 --- a/src/Primitives/CrestApps.Core.AI/Extensions/AIFunctionArgumentsExtensions.cs +++ b/src/Primitives/CrestApps.Core.AI/Extensions/AIFunctionArgumentsExtensions.cs @@ -75,4 +75,4 @@ public static bool TryGetFirst(this AIFunctionArguments arguments, string key return false; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Handlers/AIChatSessionHandlerBase.cs b/src/Primitives/CrestApps.Core.AI/Handlers/AIChatSessionHandlerBase.cs index 730f3e0e..56e31dcb 100644 --- a/src/Primitives/CrestApps.Core.AI/Handlers/AIChatSessionHandlerBase.cs +++ b/src/Primitives/CrestApps.Core.AI/Handlers/AIChatSessionHandlerBase.cs @@ -16,4 +16,4 @@ public virtual Task MessageCompletedAsync(ChatMessageCompletedContext context) { return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Handlers/AICompletionHandlerBase.cs b/src/Primitives/CrestApps.Core.AI/Handlers/AICompletionHandlerBase.cs index 4866ad72..22d425e1 100644 --- a/src/Primitives/CrestApps.Core.AI/Handlers/AICompletionHandlerBase.cs +++ b/src/Primitives/CrestApps.Core.AI/Handlers/AICompletionHandlerBase.cs @@ -14,4 +14,4 @@ public virtual Task ReceivedUpdateAsync(ReceivedUpdateContext context) { return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Handlers/AIMemoryOrchestrationContextHelper.cs b/src/Primitives/CrestApps.Core.AI/Handlers/AIMemoryOrchestrationContextHelper.cs index 531cfeca..dff05678 100644 --- a/src/Primitives/CrestApps.Core.AI/Handlers/AIMemoryOrchestrationContextHelper.cs +++ b/src/Primitives/CrestApps.Core.AI/Handlers/AIMemoryOrchestrationContextHelper.cs @@ -26,4 +26,4 @@ public static bool IsEnabled(object resource, IOptions tool.Name))); } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Handlers/AIProfileCompletionContextBuilderHandler.cs b/src/Primitives/CrestApps.Core.AI/Handlers/AIProfileCompletionContextBuilderHandler.cs index 859ed856..d09ef682 100644 --- a/src/Primitives/CrestApps.Core.AI/Handlers/AIProfileCompletionContextBuilderHandler.cs +++ b/src/Primitives/CrestApps.Core.AI/Handlers/AIProfileCompletionContextBuilderHandler.cs @@ -87,4 +87,4 @@ private async Task ResolveSystemMessageAsync(AIProfile profile, AIProfil return metadata.SystemMessage; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Handlers/AgentOrchestrationContextBuilderHandler.cs b/src/Primitives/CrestApps.Core.AI/Handlers/AgentOrchestrationContextBuilderHandler.cs index a570dbba..882be8ec 100644 --- a/src/Primitives/CrestApps.Core.AI/Handlers/AgentOrchestrationContextBuilderHandler.cs +++ b/src/Primitives/CrestApps.Core.AI/Handlers/AgentOrchestrationContextBuilderHandler.cs @@ -77,4 +77,4 @@ private sealed class AgentInfo public string Name { get; set; } public string Description { get; set; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Handlers/DataSourceAICompletionContextBuilderHandler.cs b/src/Primitives/CrestApps.Core.AI/Handlers/DataSourceAICompletionContextBuilderHandler.cs index dec1f6c8..7a763f55 100644 --- a/src/Primitives/CrestApps.Core.AI/Handlers/DataSourceAICompletionContextBuilderHandler.cs +++ b/src/Primitives/CrestApps.Core.AI/Handlers/DataSourceAICompletionContextBuilderHandler.cs @@ -23,4 +23,4 @@ public Task BuiltAsync(AICompletionContextBuiltContext context) { return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Handlers/DataSourceOrchestrationHandler.cs b/src/Primitives/CrestApps.Core.AI/Handlers/DataSourceOrchestrationHandler.cs index 52642d64..f28fa854 100644 --- a/src/Primitives/CrestApps.Core.AI/Handlers/DataSourceOrchestrationHandler.cs +++ b/src/Primitives/CrestApps.Core.AI/Handlers/DataSourceOrchestrationHandler.cs @@ -58,4 +58,4 @@ public async Task BuiltAsync(OrchestrationContextBuiltContext context) _logger.LogDebug("Enabled data-source orchestration for {ResourceType} and exposed tools: {Tools}.", context.Resource.GetType().Name, string.Join(", ", dataSourceTools.Select(tool => tool.Name))); } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Handlers/PreemptiveRagOrchestrationHandler.cs b/src/Primitives/CrestApps.Core.AI/Handlers/PreemptiveRagOrchestrationHandler.cs index 1fc0fd3b..7d2a9257 100644 --- a/src/Primitives/CrestApps.Core.AI/Handlers/PreemptiveRagOrchestrationHandler.cs +++ b/src/Primitives/CrestApps.Core.AI/Handlers/PreemptiveRagOrchestrationHandler.cs @@ -193,4 +193,4 @@ private static AIDataSourceRagMetadata GetRagMetadata(object resource) return null; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Models/AIDataSourceOptions.cs b/src/Primitives/CrestApps.Core.AI/Models/AIDataSourceOptions.cs index f489bf21..b5c8b845 100644 --- a/src/Primitives/CrestApps.Core.AI/Models/AIDataSourceOptions.cs +++ b/src/Primitives/CrestApps.Core.AI/Models/AIDataSourceOptions.cs @@ -103,4 +103,4 @@ public static AIDataSourceOptions FromSettings(AIDataSourceSettings settings) DefaultTopNDocuments = settings.DefaultTopNDocuments, }; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Models/AIMemoryOptions.cs b/src/Primitives/CrestApps.Core.AI/Models/AIMemoryOptions.cs index d81620b4..7379b73e 100644 --- a/src/Primitives/CrestApps.Core.AI/Models/AIMemoryOptions.cs +++ b/src/Primitives/CrestApps.Core.AI/Models/AIMemoryOptions.cs @@ -13,4 +13,4 @@ public AIMemoryOptions Clone() TopN = TopN, }; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Models/ChatDocumentsOptionsExtensions.cs b/src/Primitives/CrestApps.Core.AI/Models/ChatDocumentsOptionsExtensions.cs index fa361321..1760a436 100644 --- a/src/Primitives/CrestApps.Core.AI/Models/ChatDocumentsOptionsExtensions.cs +++ b/src/Primitives/CrestApps.Core.AI/Models/ChatDocumentsOptionsExtensions.cs @@ -36,4 +36,4 @@ private static string[] OrderExtensions(IEnumerable extensions) { return (extensions ?? []).Where(extension => !string.IsNullOrWhiteSpace(extension)).Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(extension => extension, StringComparer.OrdinalIgnoreCase).ToArray(); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Models/ChatInteractionMemoryOptions.cs b/src/Primitives/CrestApps.Core.AI/Models/ChatInteractionMemoryOptions.cs index a5c41287..c32d60e3 100644 --- a/src/Primitives/CrestApps.Core.AI/Models/ChatInteractionMemoryOptions.cs +++ b/src/Primitives/CrestApps.Core.AI/Models/ChatInteractionMemoryOptions.cs @@ -19,4 +19,4 @@ public static ChatInteractionMemoryOptions FromMetadata(MemoryMetadata metadata) EnableUserMemory = metadata?.EnableUserMemory ?? true, }; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Models/ExtractorExtension.cs b/src/Primitives/CrestApps.Core.AI/Models/ExtractorExtension.cs index 8a25f2d4..91cd1901 100644 --- a/src/Primitives/CrestApps.Core.AI/Models/ExtractorExtension.cs +++ b/src/Primitives/CrestApps.Core.AI/Models/ExtractorExtension.cs @@ -65,4 +65,4 @@ public static implicit operator ExtractorExtension(string extension) } public override string ToString() => Extension; -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Models/GeneralAIOptions.cs b/src/Primitives/CrestApps.Core.AI/Models/GeneralAIOptions.cs index ac92c7b1..686ab5e7 100644 --- a/src/Primitives/CrestApps.Core.AI/Models/GeneralAIOptions.cs +++ b/src/Primitives/CrestApps.Core.AI/Models/GeneralAIOptions.cs @@ -43,4 +43,4 @@ public static GeneralAIOptions FromSettings(GeneralAISettings settings) EnableOpenTelemetry = settings.EnableOpenTelemetry, }; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Models/InteractionDocumentOptions.cs b/src/Primitives/CrestApps.Core.AI/Models/InteractionDocumentOptions.cs index e0154f8f..210753ab 100644 --- a/src/Primitives/CrestApps.Core.AI/Models/InteractionDocumentOptions.cs +++ b/src/Primitives/CrestApps.Core.AI/Models/InteractionDocumentOptions.cs @@ -29,4 +29,4 @@ public static InteractionDocumentOptions FromSettings(InteractionDocumentSetting TopN = settings.TopN, }; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Models/MemoryMetadataExtensions.cs b/src/Primitives/CrestApps.Core.AI/Models/MemoryMetadataExtensions.cs index 73f2a878..a922d80f 100644 --- a/src/Primitives/CrestApps.Core.AI/Models/MemoryMetadataExtensions.cs +++ b/src/Primitives/CrestApps.Core.AI/Models/MemoryMetadataExtensions.cs @@ -102,4 +102,4 @@ private static object GetPropertyValue(IDictionary properties, s { return properties is not null && properties.TryGetValue(key, out var value) ? value : null; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Services/AIClientProviderBase.cs b/src/Primitives/CrestApps.Core.AI/Services/AIClientProviderBase.cs index 6c15a204..10345dba 100644 --- a/src/Primitives/CrestApps.Core.AI/Services/AIClientProviderBase.cs +++ b/src/Primitives/CrestApps.Core.AI/Services/AIClientProviderBase.cs @@ -108,7 +108,6 @@ public virtual ValueTask GetTextToSpeechClientAsync(AIProvi #pragma warning restore MEAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. - public virtual Task GetSpeechVoicesAsync(AIProviderConnectionEntry connection, string deploymentName = null) { return Task.FromResult(Array.Empty()); diff --git a/src/Primitives/CrestApps.Core.AI/Services/AICompletionUsageRecordFactory.cs b/src/Primitives/CrestApps.Core.AI/Services/AICompletionUsageRecordFactory.cs index cbce8bb4..10d75e04 100644 --- a/src/Primitives/CrestApps.Core.AI/Services/AICompletionUsageRecordFactory.cs +++ b/src/Primitives/CrestApps.Core.AI/Services/AICompletionUsageRecordFactory.cs @@ -56,4 +56,4 @@ public static AICompletionUsageRecord Create(IReadOnlyDictionary } private static int Normalize(long value) => value > int.MaxValue ? int.MaxValue : (int)value; -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Services/AIConfigurationRecordIds.cs b/src/Primitives/CrestApps.Core.AI/Services/AIConfigurationRecordIds.cs index d9d1c2bf..43d657e4 100644 --- a/src/Primitives/CrestApps.Core.AI/Services/AIConfigurationRecordIds.cs +++ b/src/Primitives/CrestApps.Core.AI/Services/AIConfigurationRecordIds.cs @@ -34,4 +34,4 @@ public static bool IsConfigurationDeploymentId(string itemId) { return !string.IsNullOrWhiteSpace(itemId) && itemId.StartsWith(_deploymentPrefix, StringComparison.OrdinalIgnoreCase); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Services/DefaultAIDataSourceIndexingService.cs b/src/Primitives/CrestApps.Core.AI/Services/DefaultAIDataSourceIndexingService.cs index f4ec87a5..f9c393ae 100644 --- a/src/Primitives/CrestApps.Core.AI/Services/DefaultAIDataSourceIndexingService.cs +++ b/src/Primitives/CrestApps.Core.AI/Services/DefaultAIDataSourceIndexingService.cs @@ -333,4 +333,4 @@ private static Dictionary BuildFilterFields(Dictionary> EmbeddingGenerator); -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Services/DefaultAIToolAccessEvaluator.cs b/src/Primitives/CrestApps.Core.AI/Services/DefaultAIToolAccessEvaluator.cs index a5b8468f..3e663481 100644 --- a/src/Primitives/CrestApps.Core.AI/Services/DefaultAIToolAccessEvaluator.cs +++ b/src/Primitives/CrestApps.Core.AI/Services/DefaultAIToolAccessEvaluator.cs @@ -12,4 +12,4 @@ public Task IsAuthorizedAsync(ClaimsPrincipal user, string toolName) { return Task.FromResult(true); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.AI/Services/DefaultChatResponseHandlerResolver.cs b/src/Primitives/CrestApps.Core.AI/Services/DefaultChatResponseHandlerResolver.cs index 25040550..2f498d0f 100644 --- a/src/Primitives/CrestApps.Core.AI/Services/DefaultChatResponseHandlerResolver.cs +++ b/src/Primitives/CrestApps.Core.AI/Services/DefaultChatResponseHandlerResolver.cs @@ -68,4 +68,4 @@ private IChatResponseHandler ResolveAIHandler() throw new InvalidOperationException("The default AI chat response handler is not registered. " + "Ensure CrestApps AI services are properly configured."); } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.Azure.AISearch/Services/AzureAISearchDocumentManager.cs b/src/Primitives/CrestApps.Core.Azure.AISearch/Services/AzureAISearchDocumentManager.cs index da43653e..03b2cb72 100644 --- a/src/Primitives/CrestApps.Core.Azure.AISearch/Services/AzureAISearchDocumentManager.cs +++ b/src/Primitives/CrestApps.Core.Azure.AISearch/Services/AzureAISearchDocumentManager.cs @@ -163,4 +163,4 @@ private async Task GetKeyFieldNameAsync(string indexFullName, Cancellati return "id"; } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.Azure.AISearch/Services/AzureAISearchIndexManager.cs b/src/Primitives/CrestApps.Core.Azure.AISearch/Services/AzureAISearchIndexManager.cs index de6bdc90..eb68afac 100644 --- a/src/Primitives/CrestApps.Core.Azure.AISearch/Services/AzureAISearchIndexManager.cs +++ b/src/Primitives/CrestApps.Core.Azure.AISearch/Services/AzureAISearchIndexManager.cs @@ -152,4 +152,4 @@ public async Task DeleteAsync(IIndexProfileInfo profile, CancellationToken cance throw; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.Elasticsearch/Services/ElasticsearchSearchDocumentManager.cs b/src/Primitives/CrestApps.Core.Elasticsearch/Services/ElasticsearchSearchDocumentManager.cs index bb63268f..4439eb24 100644 --- a/src/Primitives/CrestApps.Core.Elasticsearch/Services/ElasticsearchSearchDocumentManager.cs +++ b/src/Primitives/CrestApps.Core.Elasticsearch/Services/ElasticsearchSearchDocumentManager.cs @@ -120,4 +120,4 @@ public async Task DeleteAllAsync(IIndexProfileInfo profile, CancellationToken ca _logger.LogError(ex, "Error deleting all documents from Elasticsearch index '{IndexName}'.", SanitizeLogValue(profile.IndexFullName)); } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core.Elasticsearch/Services/ElasticsearchSearchIndexManager.cs b/src/Primitives/CrestApps.Core.Elasticsearch/Services/ElasticsearchSearchIndexManager.cs index fd451936..2511cf9c 100644 --- a/src/Primitives/CrestApps.Core.Elasticsearch/Services/ElasticsearchSearchIndexManager.cs +++ b/src/Primitives/CrestApps.Core.Elasticsearch/Services/ElasticsearchSearchIndexManager.cs @@ -114,4 +114,4 @@ public async Task DeleteAsync(IIndexProfileInfo profile, CancellationToken cance throw; } } -} \ No newline at end of file +} diff --git a/src/Primitives/CrestApps.Core/Handlers/CatalogEntryHandlerBase.cs b/src/Primitives/CrestApps.Core/Handlers/CatalogEntryHandlerBase.cs index 0c60de9e..5e460993 100644 --- a/src/Primitives/CrestApps.Core/Handlers/CatalogEntryHandlerBase.cs +++ b/src/Primitives/CrestApps.Core/Handlers/CatalogEntryHandlerBase.cs @@ -59,4 +59,4 @@ public virtual Task ValidatingAsync(ValidatingContext context) { return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Resources/CrestApps.AI.Resources/Assets.json b/src/Resources/CrestApps.AI.Resources/Assets.json index 08be2d34..48ba89d8 100644 --- a/src/Resources/CrestApps.AI.Resources/Assets.json +++ b/src/Resources/CrestApps.AI.Resources/Assets.json @@ -27,6 +27,13 @@ "output": "wwwroot/scripts/technical-name-generator.js", "generateSourceMaps": true }, + { + "inputs": [ + "Assets/css/ai-chat.css" + ], + "output": "wwwroot/styles/ai-chat.css", + "generateSourceMaps": true + }, { "inputs": [ "Assets/css/chat-widget.css" diff --git a/src/Resources/CrestApps.AI.Resources/Assets/css/ai-chat.css b/src/Resources/CrestApps.AI.Resources/Assets/css/ai-chat.css new file mode 100644 index 00000000..c675406a --- /dev/null +++ b/src/Resources/CrestApps.AI.Resources/Assets/css/ai-chat.css @@ -0,0 +1,360 @@ +.ai-chat-msg-role { + font-size: 1.25rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.03em; + margin-bottom: 0.35rem; +} + +.ai-chat-msg-role-user { + color: var(--bs-primary, #0d6efd); +} + +.ai-chat-msg-role-assistant { + color: var(--ai-chat-primary, #198754); +} + +.ai-chat-messages .ai-chat-message-item { + position: relative; + padding: 0.25rem 0; +} + +.ai-chat-messages .ai-chat-message-item + .ai-chat-message-item::before { + content: ''; + display: block; + width: 100%; + margin: 0.5rem auto 0.75rem; + border-top: 1px solid var(--bs-border-color, #dee2e6); +} + +.ai-chat-messages .ai-chat-message-item p:last-child { + margin-bottom: 0; +} + +.ai-chat-messages .ai-chat-message-body { + position: relative; + padding: 0; + overflow-wrap: break-word; + word-break: break-word; + min-width: 0; +} + +.ai-partial-transcript { + font-style: italic; + opacity: 0.7; +} + +.ai-chat-messages .message-buttons-container { + position: absolute; + right: 0.1rem; + bottom: 0; + display: inline-flex; + align-items: center; + gap: 0.35rem; + width: auto; + max-width: max-content; + opacity: 0; + pointer-events: none; + transition: opacity 0.15s ease-in-out; + background: rgba(255, 255, 255, 0.96); + padding: 0.2rem 0.35rem; + border-radius: 999px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); + margin-bottom: 1rem; + transform: translateY(50%); + z-index: 1; +} + +.ai-chat-messages .ai-chat-message-item:hover .message-buttons-container, +.ai-chat-messages .ai-chat-message-item:focus-within .message-buttons-container { + opacity: 1; + pointer-events: auto; +} + +.ai-chat-messages .message-buttons-container:has(.tts-playing) { + opacity: 1; + pointer-events: auto; +} + +.ai-chat-messages .message-buttons-container > .button-message-toolbox { + display: inline-flex; + align-items: center; + justify-content: center; + flex: 0 0 auto; + width: 1.75rem; + height: 1.75rem; + margin: 0 !important; + padding: 0 !important; + border-radius: 50%; + color: var(--bs-secondary-color, #6c757d) !important; + text-decoration: none; +} + +.ai-chat-messages .message-buttons-container .ai-chat-message-assistant-feedback { + display: inline-flex; + align-items: center; + gap: 0.35rem; +} + +.ai-chat-messages .message-buttons-container > .button-message-toolbox:hover, +.ai-chat-messages .message-buttons-container > .button-message-toolbox:focus { + color: var(--bs-body-color, #212529) !important; +} + +.ai-chat-messages .message-buttons-container .tts-playing { + color: var(--ai-chat-primary, #198754); +} + +@keyframes spark-burst { + 0% { + transform: scale(1); + opacity: 1; + } + 20% { + transform: scale(1.8); + opacity: 0.7; + } + 40% { + transform: scale(0.9); + opacity: 1; + } + 60% { + transform: scale(1.3); + } + 100% { + transform: scale(1); + } +} + +.spark-effect i, +.spark-effect svg { + display: inline-block; + animation: spark-burst 0.5s ease-out; +} + +.ai-chat-messages .ai-bot-icon { + color: currentColor; + display: inline-block; + animation: none; +} + +@keyframes ai-chat-streaming-effect { + 0% { opacity: 1; transform: rotate(0deg); } + 10% { opacity: 0.3; transform: rotate(0deg); } + 20% { opacity: 1; transform: rotate(0deg); } + 30% { opacity: 0.3; transform: rotate(0deg); } + 40% { opacity: 1; transform: rotate(0deg); } + 50% { opacity: 0.3; transform: rotate(0deg); } + 60% { opacity: 1; transform: rotate(0deg); } + 80% { opacity: 1; transform: rotate(360deg); } + 100% { opacity: 1; transform: rotate(360deg); } +} + +.ai-chat-messages .ai-streaming-icon { + color: currentColor; + display: inline-block; + animation: ai-chat-streaming-effect 4s ease-in-out infinite; +} + +.ai-chat-messages pre { + position: relative; + margin: 0; +} + +.ai-chat-messages .ai-code-block { + border: 1px solid var(--bs-border-color, #dee2e6); + border-radius: 0.5rem; + overflow: hidden; + margin: 0.75rem 0; + background: var(--bs-body-bg, #fff); +} + +.ai-chat-messages .ai-code-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.5rem 1rem; + font-size: 0.8rem; + min-height: 2rem; +} + +.ai-chat-messages .ai-code-lang { + font-weight: 600; + color: var(--bs-body-color, #212529); + text-transform: capitalize; +} + +.ai-chat-messages .ai-code-lang i { + color: var(--bs-secondary-color, #6c757d); + margin-right: 0.25rem; +} + +.ai-chat-messages .ai-code-copy-btn { + display: inline-flex; + align-items: center; + gap: 0.3rem; + padding: 0.2rem; + font-size: 0.8rem; + background: transparent; + border: none; + cursor: pointer; + color: var(--bs-secondary-color, #6c757d); + transition: color 0.15s; + white-space: nowrap; +} + +.ai-chat-messages .ai-code-copy-btn:hover { + color: var(--bs-body-color, #212529); +} + +.ai-chat-messages .ai-code-block pre { + margin: 0; + background: transparent !important; +} + +.ai-chat-messages .ai-code-block pre code.hljs { + background: transparent !important; + padding: 0.75rem 1rem 1rem; +} + +.ai-chat-messages pre code.hljs { + white-space: pre-wrap; + word-wrap: break-word; + overflow-wrap: break-word; + border-radius: 0.375rem; +} + +.ai-chat-doc-bar { + border-bottom: 1px solid var(--bs-border-color, #dee2e6); +} + +.ai-chat-drag-over { + outline: 2px dashed var(--bs-primary, #0d6efd) !important; + outline-offset: -2px; + background-color: rgba(13, 110, 253, 0.05) !important; +} + +.ai-chat-notification { + margin: 0.75rem 0 0.25rem; + padding: 0.625rem 0.875rem; + border-radius: 0.5rem; + border: 1px solid var(--bs-border-color, #dee2e6); + background-color: var(--bs-light, #f8f9fa); + font-size: 0.875rem; + line-height: 1.4; +} + +.ai-chat-notification-content { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.ai-chat-notification-icon { + flex-shrink: 0; + font-size: 1rem; + opacity: 0.8; +} + +.ai-chat-notification-text { + flex: 1; +} + +.ai-chat-notification-dismiss { + flex-shrink: 0; + opacity: 0.5; + transition: opacity 0.15s; +} + +.ai-chat-notification-dismiss:hover { + opacity: 1; +} + +.ai-chat-notification-actions { + display: flex; + gap: 0.375rem; + margin-top: 0.5rem; + padding-top: 0.5rem; + border-top: 1px solid var(--bs-border-color, #dee2e6); +} + +.ai-chat-notification-actions .btn { + font-size: 0.8125rem; + padding: 0.1875rem 0.625rem; +} + +.ai-chat-notification-typing { + border-color: var(--ai-chat-primary, #198754); + background-color: rgba(25, 135, 84, 0.05); +} + +.ai-chat-notification-typing .ai-chat-notification-icon { + color: var(--ai-chat-primary, #198754); + animation: ai-chat-typing-pulse 1.5s ease-in-out infinite; +} + +@keyframes ai-chat-typing-pulse { + 0%, 100% { opacity: 0.4; } + 50% { opacity: 1; } +} + +.ai-chat-notification-transfer { + border-color: var(--bs-warning, #ffc107); + background-color: rgba(255, 193, 7, 0.06); +} + +.ai-chat-notification-transfer .ai-chat-notification-icon { + color: var(--bs-warning, #ffc107); + animation: ai-chat-transfer-pulse 2s ease-in-out infinite; +} + +@keyframes ai-chat-transfer-pulse { + 0%, 100% { transform: scale(1); opacity: 0.7; } + 50% { transform: scale(1.1); opacity: 1; } +} + +.ai-chat-notification-ended, +.ai-chat-notification-session-ended, +.ai-chat-notification-conversation-ended { + border-color: var(--bs-secondary, #6c757d); + background-color: rgba(108, 117, 125, 0.05); +} + +.ai-chat-notification-ended .ai-chat-notification-icon, +.ai-chat-notification-session-ended .ai-chat-notification-icon, +.ai-chat-notification-conversation-ended .ai-chat-notification-icon { + color: var(--bs-secondary, #6c757d); +} + +.ai-chat-notification-info, +.ai-chat-notification-agent-connected { + border-color: var(--bs-info, #0dcaf0); + background-color: rgba(13, 202, 240, 0.05); +} + +.ai-chat-notification-info .ai-chat-notification-icon, +.ai-chat-notification-agent-connected .ai-chat-notification-icon { + color: var(--bs-info, #0dcaf0); +} + +.ai-chat-notification-warning, +.ai-chat-notification-agent-reconnecting { + border-color: var(--bs-warning, #ffc107); + background-color: rgba(255, 193, 7, 0.06); +} + +.ai-chat-notification-warning .ai-chat-notification-icon, +.ai-chat-notification-agent-reconnecting .ai-chat-notification-icon { + color: var(--bs-warning, #ffc107); +} + +.ai-chat-notification-error, +.ai-chat-notification-connection-lost { + border-color: var(--bs-danger, #dc3545); + background-color: rgba(220, 53, 69, 0.05); +} + +.ai-chat-notification-error .ai-chat-notification-icon, +.ai-chat-notification-connection-lost .ai-chat-notification-icon { + color: var(--bs-danger, #dc3545); +} diff --git a/src/Resources/CrestApps.AI.Resources/Assets/css/chat-widget.css b/src/Resources/CrestApps.AI.Resources/Assets/css/chat-widget.css index 4bc953dc..f60a518e 100644 --- a/src/Resources/CrestApps.AI.Resources/Assets/css/chat-widget.css +++ b/src/Resources/CrestApps.AI.Resources/Assets/css/chat-widget.css @@ -160,7 +160,7 @@ } .ai-chat-widget-messages .ai-chat-msg-role-assistant { - color: #6f42c1; + color: var(--ai-widget-primary, #6f42c1); } .ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon { @@ -168,7 +168,7 @@ } .ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon { - color: #6f42c1; + color: currentColor; } .ai-chat-widget-messages .ai-chat-message-body { @@ -211,6 +211,11 @@ pointer-events: auto; } +.ai-chat-widget-messages .message-buttons-container:has(.tts-playing) { + opacity: 1; + pointer-events: auto; +} + .ai-chat-widget-messages .message-buttons-container > .button-message-toolbox { display: inline-flex; align-items: center; @@ -237,11 +242,76 @@ } .ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing { - color: var(--bs-primary, #0d6efd) !important; + color: var(--ai-widget-primary, #6f42c1) !important; opacity: 1; pointer-events: auto; } +.ai-chat-widget-history-panel { + position: absolute; + top: 3.5rem; + left: 0; + right: 0; + bottom: 0; + background: #fff; + padding: 1rem; + z-index: 10; + display: none; + overflow-y: auto; + flex-direction: column; +} + +.ai-chat-widget-history-panel.show { + display: flex; +} + +.ai-chat-widget-history-panel .history-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.75rem; + flex-shrink: 0; +} + +.ai-chat-widget-history-panel .history-header h5 { + margin: 0; + font-size: 1rem; +} + +.ai-chat-widget-history-list { + list-style: none; + padding: 0; + margin: 0; + overflow-y: auto; + flex: 1 1 auto; +} + +.ai-chat-widget-history-list li { + margin-bottom: 0; +} + +.ai-chat-widget-history-list .chat-session-history-item { + display: block; + padding: 0.5rem 0.75rem; + text-decoration: none; + color: var(--bs-body-color, #212529); + font-size: 0.85rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + transition: background 0.15s; + cursor: pointer; + border-bottom: 1px solid var(--bs-border-color, #dee2e6); +} + +.ai-chat-widget-history-list li:last-child .chat-session-history-item { + border-bottom: none; +} + +.ai-chat-widget-history-list .chat-session-history-item:hover { + background: var(--bs-tertiary-bg, #f8f9fa); +} + /* ── Notifications ── */ .ai-chat-widget-messages .ai-chat-notification { margin: 0.75rem 0.5rem 0; @@ -308,12 +378,20 @@ border-top: 1px solid #e9ecef; padding: 0.5rem 0.75rem; display: flex; + flex-wrap: wrap; gap: 0.5rem; align-items: flex-end; } +.ai-chat-widget-input .ai-chat-doc-bar { + flex: 0 0 100%; + margin: -0.5rem -0.75rem 0.5rem; + padding: 0.5rem 0.75rem; +} + .ai-chat-widget-input textarea { flex: 1; + min-width: 0; border: 1px solid #ced4da; border-radius: 8px; padding: 0.4rem 0.6rem; @@ -341,6 +419,29 @@ white-space: nowrap; } +.ai-chat-widget-input .btn { + background: var(--bs-body-bg, #fff); + color: var(--bs-body-color, #212529); + border: 1px solid var(--bs-border-color, #ced4da); +} + +.ai-chat-widget-input .btn.btn-link { + background: transparent; + color: var(--bs-secondary-color, #6c757d); + border: none; + padding: 0.4rem; +} + +.ai-chat-widget-input .btn.btn-outline-dark { + background: var(--bs-dark, #212529); + color: #fff; + border-color: var(--bs-dark, #212529); +} + +.ai-chat-widget-input .btn.btn-outline-secondary { + color: var(--bs-secondary-color, #6c757d); +} + .ai-chat-widget-input button:disabled { opacity: 0.5; cursor: not-allowed; diff --git a/src/Resources/CrestApps.AI.Resources/Assets/js/ai-chat.js b/src/Resources/CrestApps.AI.Resources/Assets/js/ai-chat.js index b8b377b1..479bb797 100644 --- a/src/Resources/CrestApps.AI.Resources/Assets/js/ai-chat.js +++ b/src/Resources/CrestApps.AI.Resources/Assets/js/ai-chat.js @@ -549,8 +549,8 @@ window.openAIChatManager = function () { nextLayout.panel = Object.assign({}, currentLayout.panel || {}, partialLayout.panel || {}); } - if (partialLayout.toggle !== undefined) { - nextLayout.toggle = Object.assign({}, currentLayout.toggle || {}, partialLayout.toggle || {}); + if (partialLayout.position !== undefined) { + nextLayout.position = Object.assign({}, currentLayout.position || {}, partialLayout.position || {}); } localStorage.setItem(this.chatWidgetLayoutKey, JSON.stringify(nextLayout)); @@ -571,6 +571,33 @@ window.openAIChatManager = function () { height: Math.round(rect.height || parsePixelValue(computed.height) || fallbackHeight || 0) }; }, + getElementPosition(element) { + if (!element) { + return { + left: 0, + top: 0 + }; + } + + var rect = element.getBoundingClientRect(); + var computed = window.getComputedStyle(element); + var inlineLeft = parsePixelValue(element.style.left); + var inlineTop = parsePixelValue(element.style.top); + var computedLeft = parsePixelValue(computed.left); + var computedTop = parsePixelValue(computed.top); + var isHidden = computed.display === 'none'; + + return { + left: Math.round( + isHidden && Number.isFinite(inlineLeft) + ? inlineLeft + : rect.left || inlineLeft || computedLeft || 0), + top: Math.round( + isHidden && Number.isFinite(inlineTop) + ? inlineTop + : rect.top || inlineTop || computedTop || 0) + }; + }, clampWidgetPosition(left, top, width, height) { var viewportPadding = 8; var maxLeft = Math.max(viewportPadding, window.innerWidth - width - viewportPadding); @@ -597,16 +624,36 @@ window.openAIChatManager = function () { height: this.widgetDefaultHeight || parsePixelValue(config.widget.defaultHeight) || 520 }; }, + getWidgetToggleGap() { + return 8; + }, + isWidgetPanelVisible() { + if (!this.widgetContainerElement) { + return false; + } + + var computed = window.getComputedStyle(this.widgetContainerElement); + return this.widgetContainerElement.classList.contains('open') && computed.display !== 'none'; + }, persistWidgetPanelPosition() { if (!this.widgetContainerElement || !config.widget.persistLayout) { return; } - var panelRect = this.widgetContainerElement.getBoundingClientRect(); + var panelDefaultSize = this.getWidgetDefaultSize(); + var panelPosition = this.getElementPosition(this.widgetContainerElement); + var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height); + var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52); + var linkedPosition = this.clampWidgetPosition( + panelPosition.left + panelSize.width - toggleSize.width, + panelPosition.top + panelSize.height + this.getWidgetToggleGap(), + toggleSize.width, + toggleSize.height); + this.saveStoredWidgetLayout({ - panel: { - left: Math.round(panelRect.left), - top: Math.round(panelRect.top) + position: { + left: linkedPosition.left, + top: linkedPosition.top } }); }, @@ -617,9 +664,9 @@ window.openAIChatManager = function () { var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect(); this.saveStoredWidgetLayout({ - toggle: { - left: Math.round(toggleRect.left), - top: Math.round(toggleRect.top) + position: { + left: this.getElementPosition(this.widgetToggleButtonElement).left, + top: this.getElementPosition(this.widgetToggleButtonElement).top } }); }, @@ -638,6 +685,48 @@ window.openAIChatManager = function () { } }); }, + syncTogglePositionToPanel(persistLayout = true) { + if (!this.widgetContainerElement || !this.widgetToggleButtonElement) { + return; + } + + var panelDefaultSize = this.getWidgetDefaultSize(); + var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height); + var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52); + var panelPosition = this.getElementPosition(this.widgetContainerElement); + var linkedPosition = this.clampWidgetPosition( + panelPosition.left + panelSize.width - toggleSize.width, + panelPosition.top + panelSize.height + this.getWidgetToggleGap(), + toggleSize.width, + toggleSize.height); + + this.applyAbsolutePosition(this.widgetToggleButtonElement, linkedPosition.left, linkedPosition.top); + + if (persistLayout && config.widget.persistLayout) { + this.persistWidgetTogglePosition(); + } + }, + syncPanelPositionToToggle(persistLayout = true) { + if (!this.widgetContainerElement || !this.widgetToggleButtonElement) { + return; + } + + var panelDefaultSize = this.getWidgetDefaultSize(); + var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height); + var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52); + var togglePosition = this.getElementPosition(this.widgetToggleButtonElement); + var linkedPosition = this.clampWidgetPosition( + togglePosition.left + toggleSize.width - panelSize.width, + togglePosition.top - panelSize.height - this.getWidgetToggleGap(), + panelSize.width, + panelSize.height); + + this.applyAbsolutePosition(this.widgetContainerElement, linkedPosition.left, linkedPosition.top); + + if (persistLayout && config.widget.persistLayout) { + this.persistWidgetPanelPosition(); + } + }, updateWidgetResetSizeButtonVisibility() { if (!this.widgetResetSizeButtonElement) { return; @@ -686,16 +775,21 @@ window.openAIChatManager = function () { } } - if (this.widgetContainerElement && config.widget.enableDragging && - Number.isFinite(storedLayout.panel && storedLayout.panel.left) && - Number.isFinite(storedLayout.panel && storedLayout.panel.top)) { - this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top); - } - if (this.widgetToggleButtonElement && config.widget.enableDragging && + Number.isFinite(storedLayout.position && storedLayout.position.left) && + Number.isFinite(storedLayout.position && storedLayout.position.top)) { + this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.position.left, storedLayout.position.top); + this.syncPanelPositionToToggle(false); + } else if (this.widgetToggleButtonElement && config.widget.enableDragging && Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) && Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) { this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.toggle.left, storedLayout.toggle.top); + this.syncPanelPositionToToggle(false); + } else if (this.widgetContainerElement && config.widget.enableDragging && + Number.isFinite(storedLayout.panel && storedLayout.panel.left) && + Number.isFinite(storedLayout.panel && storedLayout.panel.top)) { + this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top); + this.syncTogglePositionToPanel(false); } this.constrainWidgetElementsToViewport(); @@ -735,8 +829,15 @@ window.openAIChatManager = function () { } if (layoutKey === 'panel') { + this.syncTogglePositionToPanel(false); this.persistWidgetPanelPosition(); } else if (layoutKey === 'toggle') { + this.syncPanelPositionToToggle(false); + this.persistWidgetTogglePosition(); + } + + if (config.widget.persistLayout) { + this.persistWidgetPanelPosition(); this.persistWidgetTogglePosition(); } @@ -776,6 +877,12 @@ window.openAIChatManager = function () { currentSize.height); this.applyAbsolutePosition(element, nextPosition.left, nextPosition.top); + + if (layoutKey === 'panel') { + this.syncTogglePositionToPanel(false); + } else if (layoutKey === 'toggle') { + this.syncPanelPositionToToggle(false); + } }; handle.addEventListener('pointerdown', (event) => { @@ -807,28 +914,30 @@ window.openAIChatManager = function () { }); }, constrainWidgetElementsToViewport() { - if (this.widgetContainerElement && this.widgetContainerElement.style.left) { + if (this.widgetContainerElement && this.widgetContainerElement.style.left && this.isWidgetPanelVisible()) { var panelDefaultSize = this.getWidgetDefaultSize(); var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height); - var panelRect = this.widgetContainerElement.getBoundingClientRect(); - var clampedPanel = this.clampWidgetPosition(panelRect.left, panelRect.top, panelSize.width, panelSize.height); + var panelPosition = this.getElementPosition(this.widgetContainerElement); + var clampedPanel = this.clampWidgetPosition(panelPosition.left, panelPosition.top, panelSize.width, panelSize.height); this.applyAbsolutePosition(this.widgetContainerElement, clampedPanel.left, clampedPanel.top); + this.syncTogglePositionToPanel(false); if (config.widget.persistLayout) { this.persistWidgetPanelPosition(); + this.persistWidgetTogglePosition(); } - } - - if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) { + } else if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) { var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52); - var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect(); - var clampedToggle = this.clampWidgetPosition(toggleRect.left, toggleRect.top, toggleSize.width, toggleSize.height); + var togglePosition = this.getElementPosition(this.widgetToggleButtonElement); + var clampedToggle = this.clampWidgetPosition(togglePosition.left, togglePosition.top, toggleSize.width, toggleSize.height); this.applyAbsolutePosition(this.widgetToggleButtonElement, clampedToggle.left, clampedToggle.top); + this.syncPanelPositionToToggle(false); if (config.widget.persistLayout) { this.persistWidgetTogglePosition(); + this.persistWidgetPanelPosition(); } } }, diff --git a/src/Resources/CrestApps.AI.Resources/package.json b/src/Resources/CrestApps.AI.Resources/package.json index 92de34d8..425ee78e 100644 --- a/src/Resources/CrestApps.AI.Resources/package.json +++ b/src/Resources/CrestApps.AI.Resources/package.json @@ -39,6 +39,9 @@ "./chat-interaction.min": "./dist/chat-interaction.min.js", "./chat-interaction.js.map": "./dist/chat-interaction.js.map", "./chat-interaction.min.js.map": "./dist/chat-interaction.min.js.map", + "./ai-chat.css": "./dist/ai-chat.css", + "./ai-chat.min.css": "./dist/ai-chat.min.css", + "./ai-chat.css.map": "./dist/ai-chat.css.map", "./document-drop-zone": "./dist/document-drop-zone.js", "./document-drop-zone.min": "./dist/document-drop-zone.min.js", "./document-drop-zone.js.map": "./dist/document-drop-zone.js.map", diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js index 88e26405..48b5b184 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js @@ -482,8 +482,8 @@ window.openAIChatManager = function () { if (partialLayout.panel !== undefined) { nextLayout.panel = Object.assign({}, currentLayout.panel || {}, partialLayout.panel || {}); } - if (partialLayout.toggle !== undefined) { - nextLayout.toggle = Object.assign({}, currentLayout.toggle || {}, partialLayout.toggle || {}); + if (partialLayout.position !== undefined) { + nextLayout.position = Object.assign({}, currentLayout.position || {}, partialLayout.position || {}); } localStorage.setItem(this.chatWidgetLayoutKey, JSON.stringify(nextLayout)); }, @@ -501,6 +501,25 @@ window.openAIChatManager = function () { height: Math.round(rect.height || parsePixelValue(computed.height) || fallbackHeight || 0) }; }, + getElementPosition: function getElementPosition(element) { + if (!element) { + return { + left: 0, + top: 0 + }; + } + var rect = element.getBoundingClientRect(); + var computed = window.getComputedStyle(element); + var inlineLeft = parsePixelValue(element.style.left); + var inlineTop = parsePixelValue(element.style.top); + var computedLeft = parsePixelValue(computed.left); + var computedTop = parsePixelValue(computed.top); + var isHidden = computed.display === 'none'; + return { + left: Math.round(isHidden && Number.isFinite(inlineLeft) ? inlineLeft : rect.left || inlineLeft || computedLeft || 0), + top: Math.round(isHidden && Number.isFinite(inlineTop) ? inlineTop : rect.top || inlineTop || computedTop || 0) + }; + }, clampWidgetPosition: function clampWidgetPosition(left, top, width, height) { var viewportPadding = 8; var maxLeft = Math.max(viewportPadding, window.innerWidth - width - viewportPadding); @@ -525,15 +544,29 @@ window.openAIChatManager = function () { height: this.widgetDefaultHeight || parsePixelValue(config.widget.defaultHeight) || 520 }; }, + getWidgetToggleGap: function getWidgetToggleGap() { + return 8; + }, + isWidgetPanelVisible: function isWidgetPanelVisible() { + if (!this.widgetContainerElement) { + return false; + } + var computed = window.getComputedStyle(this.widgetContainerElement); + return this.widgetContainerElement.classList.contains('open') && computed.display !== 'none'; + }, persistWidgetPanelPosition: function persistWidgetPanelPosition() { if (!this.widgetContainerElement || !config.widget.persistLayout) { return; } - var panelRect = this.widgetContainerElement.getBoundingClientRect(); + var panelDefaultSize = this.getWidgetDefaultSize(); + var panelPosition = this.getElementPosition(this.widgetContainerElement); + var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height); + var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52); + var linkedPosition = this.clampWidgetPosition(panelPosition.left + panelSize.width - toggleSize.width, panelPosition.top + panelSize.height + this.getWidgetToggleGap(), toggleSize.width, toggleSize.height); this.saveStoredWidgetLayout({ - panel: { - left: Math.round(panelRect.left), - top: Math.round(panelRect.top) + position: { + left: linkedPosition.left, + top: linkedPosition.top } }); }, @@ -543,9 +576,9 @@ window.openAIChatManager = function () { } var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect(); this.saveStoredWidgetLayout({ - toggle: { - left: Math.round(toggleRect.left), - top: Math.round(toggleRect.top) + position: { + left: this.getElementPosition(this.widgetToggleButtonElement).left, + top: this.getElementPosition(this.widgetToggleButtonElement).top } }); }, @@ -562,6 +595,36 @@ window.openAIChatManager = function () { } }); }, + syncTogglePositionToPanel: function syncTogglePositionToPanel() { + var persistLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + if (!this.widgetContainerElement || !this.widgetToggleButtonElement) { + return; + } + var panelDefaultSize = this.getWidgetDefaultSize(); + var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height); + var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52); + var panelPosition = this.getElementPosition(this.widgetContainerElement); + var linkedPosition = this.clampWidgetPosition(panelPosition.left + panelSize.width - toggleSize.width, panelPosition.top + panelSize.height + this.getWidgetToggleGap(), toggleSize.width, toggleSize.height); + this.applyAbsolutePosition(this.widgetToggleButtonElement, linkedPosition.left, linkedPosition.top); + if (persistLayout && config.widget.persistLayout) { + this.persistWidgetTogglePosition(); + } + }, + syncPanelPositionToToggle: function syncPanelPositionToToggle() { + var persistLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + if (!this.widgetContainerElement || !this.widgetToggleButtonElement) { + return; + } + var panelDefaultSize = this.getWidgetDefaultSize(); + var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height); + var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52); + var togglePosition = this.getElementPosition(this.widgetToggleButtonElement); + var linkedPosition = this.clampWidgetPosition(togglePosition.left + toggleSize.width - panelSize.width, togglePosition.top - panelSize.height - this.getWidgetToggleGap(), panelSize.width, panelSize.height); + this.applyAbsolutePosition(this.widgetContainerElement, linkedPosition.left, linkedPosition.top); + if (persistLayout && config.widget.persistLayout) { + this.persistWidgetPanelPosition(); + } + }, updateWidgetResetSizeButtonVisibility: function updateWidgetResetSizeButtonVisibility() { if (!this.widgetResetSizeButtonElement) { return; @@ -599,11 +662,15 @@ window.openAIChatManager = function () { this.widgetContainerElement.style.removeProperty('height'); } } - if (this.widgetContainerElement && config.widget.enableDragging && Number.isFinite(storedLayout.panel && storedLayout.panel.left) && Number.isFinite(storedLayout.panel && storedLayout.panel.top)) { - this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top); - } - if (this.widgetToggleButtonElement && config.widget.enableDragging && Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) && Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) { + if (this.widgetToggleButtonElement && config.widget.enableDragging && Number.isFinite(storedLayout.position && storedLayout.position.left) && Number.isFinite(storedLayout.position && storedLayout.position.top)) { + this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.position.left, storedLayout.position.top); + this.syncPanelPositionToToggle(false); + } else if (this.widgetToggleButtonElement && config.widget.enableDragging && Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) && Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) { this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.toggle.left, storedLayout.toggle.top); + this.syncPanelPositionToToggle(false); + } else if (this.widgetContainerElement && config.widget.enableDragging && Number.isFinite(storedLayout.panel && storedLayout.panel.left) && Number.isFinite(storedLayout.panel && storedLayout.panel.top)) { + this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top); + this.syncTogglePositionToPanel(false); } this.constrainWidgetElementsToViewport(); this.updateWidgetResetSizeButtonVisibility(); @@ -637,8 +704,14 @@ window.openAIChatManager = function () { return; } if (layoutKey === 'panel') { + _this.syncTogglePositionToPanel(false); _this.persistWidgetPanelPosition(); } else if (layoutKey === 'toggle') { + _this.syncPanelPositionToToggle(false); + _this.persistWidgetTogglePosition(); + } + if (config.widget.persistLayout) { + _this.persistWidgetPanelPosition(); _this.persistWidgetTogglePosition(); } if (suppressClickOnDrag) { @@ -664,6 +737,11 @@ window.openAIChatManager = function () { var currentSize = _this.getElementSize(element, layoutKey === 'panel' ? defaultSize.width : 52, layoutKey === 'panel' ? defaultSize.height : 52); var nextPosition = _this.clampWidgetPosition(startLeft + deltaX, startTop + deltaY, currentSize.width, currentSize.height); _this.applyAbsolutePosition(element, nextPosition.left, nextPosition.top); + if (layoutKey === 'panel') { + _this.syncTogglePositionToPanel(false); + } else if (layoutKey === 'toggle') { + _this.syncPanelPositionToToggle(false); + } }; handle.addEventListener('pointerdown', function (event) { if (event.button !== 0) { @@ -690,23 +768,26 @@ window.openAIChatManager = function () { }); }, constrainWidgetElementsToViewport: function constrainWidgetElementsToViewport() { - if (this.widgetContainerElement && this.widgetContainerElement.style.left) { + if (this.widgetContainerElement && this.widgetContainerElement.style.left && this.isWidgetPanelVisible()) { var panelDefaultSize = this.getWidgetDefaultSize(); var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height); - var panelRect = this.widgetContainerElement.getBoundingClientRect(); - var clampedPanel = this.clampWidgetPosition(panelRect.left, panelRect.top, panelSize.width, panelSize.height); + var panelPosition = this.getElementPosition(this.widgetContainerElement); + var clampedPanel = this.clampWidgetPosition(panelPosition.left, panelPosition.top, panelSize.width, panelSize.height); this.applyAbsolutePosition(this.widgetContainerElement, clampedPanel.left, clampedPanel.top); + this.syncTogglePositionToPanel(false); if (config.widget.persistLayout) { this.persistWidgetPanelPosition(); + this.persistWidgetTogglePosition(); } - } - if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) { + } else if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) { var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52); - var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect(); - var clampedToggle = this.clampWidgetPosition(toggleRect.left, toggleRect.top, toggleSize.width, toggleSize.height); + var togglePosition = this.getElementPosition(this.widgetToggleButtonElement); + var clampedToggle = this.clampWidgetPosition(togglePosition.left, togglePosition.top, toggleSize.width, toggleSize.height); this.applyAbsolutePosition(this.widgetToggleButtonElement, clampedToggle.left, clampedToggle.top); + this.syncPanelPositionToToggle(false); if (config.widget.persistLayout) { this.persistWidgetTogglePosition(); + this.persistWidgetPanelPosition(); } } }, diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js.map b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js.map index 52553bb5..99b3a910 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js.map +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.js.map @@ -1 +1 @@ -{"version":3,"sources":["ai-chat.js"],"names":["e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","setPrototypeOf","__proto__","displayName","_regenerator","w","m","defineProperty","_regeneratorDefine","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_createForOfIteratorHelper","Array","isArray","_unsupportedIterableToArray","_n","F","s","next","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_nonIterableSpread","from","_arrayLikeToArray","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","parsePixelValue","Number","isFinite","parsed","parseFloat","clamp","min","max","Math","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$link","normalized","assign","index","Index","Text","link","Link","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","renderer","marked","Renderer","data","href","concat","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","createChartHtml","chartId","use","extensions","level","start","idx","indexOf","undefined","tokenizer","extracted","tryExtractChartMarker","startIndex","type","raw","substring","endIndex","json","token","config","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","renderChartsInMessage","message","charts","requestAnimationFrame","_iterator","_step","renderChartOnCanvas","err","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","renderPendingCharts","configs","_i2","_Object$keys","keys","parseMarkdownContent","content","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","initialize","instanceConfig","hasWidgetConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","app","Vue","createApp","inputElement","buttonElement","chatContainer","placeholder","isSessionStarted","isPlaceholderVisible","chatWidgetStateSession","chatWidgetLayoutKey","widgetContainerElement","widgetToggleButtonElement","widgetResetSizeButtonElement","widgetResizeObserver","widgetViewportResizeHandler","widgetDefaultWidth","widgetDefaultHeight","widgetIsInitialized","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","getStoredWidgetLayout","storedLayout","localStorage","getItem","saveStoredWidgetLayout","partialLayout","currentLayout","nextLayout","panel","toggle","setItem","stringify","getElementSize","element","fallbackWidth","fallbackHeight","width","height","rect","getBoundingClientRect","getComputedStyle","round","clampWidgetPosition","left","top","viewportPadding","maxLeft","innerWidth","maxTop","innerHeight","applyAbsolutePosition","style","right","bottom","getWidgetDefaultSize","persistWidgetPanelPosition","panelRect","persistWidgetTogglePosition","toggleRect","persistWidgetPanelSize","defaultSize","currentSize","abs","updateWidgetResetSizeButtonVisibility","classList","add","isResized","resetWidgetSize","removeProperty","constrainWidgetElementsToViewport","restoreWidgetLayout","attachDraggableWidgetElement","handle","layoutKey","suppressClickOnDrag","_this","activePointerId","startX","startY","startLeft","startTop","dragged","dragThreshold","interactiveSelector","stopDragging","event","pointerId","removeEventListener","onPointerMove","remove","dataset","dragSuppressClick","setTimeout","deltaX","clientX","deltaY","clientY","hypot","nextPosition","addEventListener","button","target","closest","setPointerCapture","preventDefault","panelDefaultSize","panelSize","clampedPanel","toggleSize","clampedToggle","handleDragOver","sessionDocumentsEnabled","stopPropagation","inputArea","handleDragLeave","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","_this2","_callee","sessionId","profileId","formData","response","errorText","uploadError","result","j","_t","_context","uploadDocumentUrl","getSessionId","getProfileId","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","fileName","initializeSession","uploaded","failed","removeDocument","doc","_this3","_callee2","removeError","_t2","_context2","removeDocumentUrl","headers","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","self","closeButtons","querySelectorAll","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","querySelector","div","fallbackMessage","startsWith","title","detail","normalizeAssistantAppearance","appearance","label","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this4","_callee3","_t3","_context3","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","forEach","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","_attemptedSessionRecovery","removeItem","startNewSession","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","escaped","replace","_conversationPartialMessage","hidePlaceholder","htmlContent","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentSession","autoCreateSession","onclose","addMessageInternal","_this5","fireEvent","CustomEvent","_this6","processedContent","citedRefs","filter","_ref4","_ref5","includes","sort","_ref6","_ref7","_ref8","_ref9","b","displayIndex","_iterator2","_step2","_step2$value","replaceAll","_displayIndex","_placeholder","_iterator3","_step3","_step3$value","_iterator4","_step4","_step4$value","addMessages","_this7","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","display","conversationButtonElement","isIndicator","trimmedPrompt","streamMessage","startRecording","_this8","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee4","uint8Array","base64","_context4","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this9","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_i4","_Object$entries3","_Object$entries3$_i","_this9$stream","processReferences","streamingFinished","synthesizeSpeech","_this9$stream2","getServiceDownMessage","_this0","_ref1","_ref10","_ref11","_ref12","_ref13","_ref14","processed","_iterator5","_step5","_step5$value","_iterator6","_step6","_step6$value","_iterator7","_step7","_step7$value","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","playAudioBlob","totalLength","sum","combined","offset","_iterator8","_step8","set","blob","Blob","_this10","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","nextBlob","shift","conversationModeOnAudioEnded","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this11","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","micSource","createMediaStreamSource","connect","analyser","interruptVolumeThreshold","freqData","frequencyBinCount","getByteFrequencyData","k","avg","_callee5","_context5","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","toLowerCase","location","origin","searchParams","originalLength","removedCount","_this12","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this13","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this14","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","sessionRating","initializeApp","_this15","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","threshold","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","initializeWidget","_this16","ResizeObserver","observe","dragHandle","copyResponse","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","FontAwesome","dom","i2svg","node","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","watch","handler","deep","active","mounted","_this17","_callee6","_context6","beforeUnmount","template","mount","download","toDataURL","img","res","removeChild"],"mappings":";;;;;0BACA,uKAAAA,CAAA,EAAAC,CAAA,EAAAC,CAAA,wBAAAC,MAAA,GAAAA,MAAA,OAAAC,CAAA,GAAAF,CAAA,CAAAG,QAAA,kBAAAC,CAAA,GAAAJ,CAAA,CAAAK,WAAA,8BAAAC,EAAAN,CAAA,EAAAE,CAAA,EAAAE,CAAA,EAAAE,CAAA,QAAAC,CAAA,GAAAL,CAAA,IAAAA,CAAA,CAAAM,SAAA,YAAAC,SAAA,GAAAP,CAAA,GAAAO,SAAA,EAAAC,CAAA,GAAAC,MAAA,CAAAC,MAAA,CAAAL,CAAA,CAAAC,SAAA,UAAAK,mBAAA,CAAAH,CAAA,uBAAAV,CAAA,EAAAE,CAAA,EAAAE,CAAA,QAAAE,CAAA,EAAAC,CAAA,EAAAG,CAAA,EAAAI,CAAA,MAAAC,CAAA,GAAAX,CAAA,QAAAY,CAAA,OAAAC,CAAA,KAAAF,CAAA,KAAAb,CAAA,KAAAgB,CAAA,EAAApB,CAAA,EAAAqB,CAAA,EAAAC,CAAA,EAAAN,CAAA,EAAAM,CAAA,CAAAC,IAAA,CAAAvB,CAAA,MAAAsB,CAAA,WAAAA,EAAArB,CAAA,EAAAC,CAAA,WAAAM,CAAA,GAAAP,CAAA,EAAAQ,CAAA,MAAAG,CAAA,GAAAZ,CAAA,EAAAmB,CAAA,CAAAf,CAAA,GAAAF,CAAA,EAAAmB,CAAA,gBAAAC,EAAApB,CAAA,EAAAE,CAAA,SAAAK,CAAA,GAAAP,CAAA,EAAAU,CAAA,GAAAR,CAAA,EAAAH,CAAA,OAAAiB,CAAA,IAAAF,CAAA,KAAAV,CAAA,IAAAL,CAAA,GAAAgB,CAAA,CAAAO,MAAA,EAAAvB,CAAA,UAAAK,CAAA,EAAAE,CAAA,GAAAS,CAAA,CAAAhB,CAAA,GAAAqB,CAAA,GAAAH,CAAA,CAAAF,CAAA,EAAAQ,CAAA,GAAAjB,CAAA,KAAAN,CAAA,QAAAI,CAAA,GAAAmB,CAAA,KAAArB,CAAA,MAAAQ,CAAA,GAAAJ,CAAA,EAAAC,CAAA,GAAAD,CAAA,YAAAC,CAAA,WAAAD,CAAA,MAAAA,CAAA,MAAAR,CAAA,IAAAQ,CAAA,OAAAc,CAAA,MAAAhB,CAAA,GAAAJ,CAAA,QAAAoB,CAAA,GAAAd,CAAA,QAAAC,CAAA,MAAAU,CAAA,CAAAC,CAAA,GAAAhB,CAAA,EAAAe,CAAA,CAAAf,CAAA,GAAAI,CAAA,OAAAc,CAAA,GAAAG,CAAA,KAAAnB,CAAA,GAAAJ,CAAA,QAAAM,CAAA,MAAAJ,CAAA,IAAAA,CAAA,GAAAqB,CAAA,MAAAjB,CAAA,MAAAN,CAAA,EAAAM,CAAA,MAAAJ,CAAA,EAAAe,CAAA,CAAAf,CAAA,GAAAqB,CAAA,EAAAhB,CAAA,cAAAH,CAAA,IAAAJ,CAAA,aAAAmB,CAAA,QAAAH,CAAA,OAAAd,CAAA,qBAAAE,CAAA,EAAAW,CAAA,EAAAQ,CAAA,QAAAT,CAAA,YAAAU,SAAA,uCAAAR,CAAA,UAAAD,CAAA,IAAAK,CAAA,CAAAL,CAAA,EAAAQ,CAAA,GAAAhB,CAAA,GAAAQ,CAAA,EAAAL,CAAA,GAAAa,CAAA,GAAAxB,CAAA,GAAAQ,CAAA,OAAAT,CAAA,GAAAY,CAAA,MAAAM,CAAA,KAAAV,CAAA,KAAAC,CAAA,GAAAA,CAAA,QAAAA,CAAA,SAAAU,CAAA,CAAAf,CAAA,QAAAkB,CAAA,CAAAb,CAAA,EAAAG,CAAA,KAAAO,CAAA,CAAAf,CAAA,GAAAQ,CAAA,GAAAO,CAAA,CAAAC,CAAA,GAAAR,CAAA,aAAAI,CAAA,MAAAR,CAAA,QAAAC,CAAA,KAAAH,CAAA,YAAAL,CAAA,GAAAO,CAAA,CAAAF,CAAA,WAAAL,CAAA,GAAAA,CAAA,CAAA0B,IAAA,CAAAnB,CAAA,EAAAI,CAAA,UAAAc,SAAA,2CAAAzB,CAAA,CAAA2B,IAAA,SAAA3B,CAAA,EAAAW,CAAA,GAAAX,CAAA,CAAA4B,KAAA,EAAApB,CAAA,SAAAA,CAAA,oBAAAA,CAAA,KAAAR,CAAA,GAAAO,CAAA,eAAAP,CAAA,CAAA0B,IAAA,CAAAnB,CAAA,GAAAC,CAAA,SAAAG,CAAA,GAAAc,SAAA,uCAAApB,CAAA,gBAAAG,CAAA,OAAAD,CAAA,GAAAR,CAAA,cAAAC,CAAA,IAAAiB,CAAA,GAAAC,CAAA,CAAAf,CAAA,QAAAQ,CAAA,GAAAV,CAAA,CAAAyB,IAAA,CAAAvB,CAAA,EAAAe,CAAA,OAAAE,CAAA,kBAAApB,CAAA,IAAAO,CAAA,GAAAR,CAAA,EAAAS,CAAA,MAAAG,CAAA,GAAAX,CAAA,cAAAe,CAAA,mBAAAa,KAAA,EAAA5B,CAAA,EAAA2B,IAAA,EAAAV,CAAA,SAAAhB,CAAA,EAAAI,CAAA,EAAAE,CAAA,QAAAI,CAAA,QAAAS,CAAA,gBAAAV,UAAA,cAAAmB,kBAAA,cAAAC,2BAAA,KAAA9B,CAAA,GAAAY,MAAA,CAAAmB,cAAA,MAAAvB,CAAA,MAAAL,CAAA,IAAAH,CAAA,CAAAA,CAAA,IAAAG,CAAA,SAAAW,mBAAA,CAAAd,CAAA,OAAAG,CAAA,iCAAAH,CAAA,GAAAW,CAAA,GAAAmB,0BAAA,CAAArB,SAAA,GAAAC,SAAA,CAAAD,SAAA,GAAAG,MAAA,CAAAC,MAAA,CAAAL,CAAA,YAAAO,EAAAhB,CAAA,WAAAa,MAAA,CAAAoB,cAAA,GAAApB,MAAA,CAAAoB,cAAA,CAAAjC,CAAA,EAAA+B,0BAAA,KAAA/B,CAAA,CAAAkC,SAAA,GAAAH,0BAAA,EAAAhB,mBAAA,CAAAf,CAAA,EAAAM,CAAA,yBAAAN,CAAA,CAAAU,SAAA,GAAAG,MAAA,CAAAC,MAAA,CAAAF,CAAA,GAAAZ,CAAA,WAAA8B,iBAAA,CAAApB,SAAA,GAAAqB,0BAAA,EAAAhB,mBAAA,CAAAH,CAAA,iBAAAmB,0BAAA,GAAAhB,mBAAA,CAAAgB,0BAAA,iBAAAD,iBAAA,GAAAA,iBAAA,CAAAK,WAAA,wBAAApB,mBAAA,CAAAgB,0BAAA,EAAAzB,CAAA,wBAAAS,mBAAA,CAAAH,CAAA,GAAAG,mBAAA,CAAAH,CAAA,EAAAN,CAAA,gBAAAS,mBAAA,CAAAH,CAAA,EAAAR,CAAA,iCAAAW,mBAAA,CAAAH,CAAA,8DAAAwB,YAAA,YAAAA,aAAA,aAAAC,CAAA,EAAA7B,CAAA,EAAA8B,CAAA,EAAAtB,CAAA;AAAA,SAAAD,oBAAAf,CAAA,EAAAE,CAAA,EAAAE,CAAA,EAAAH,CAAA,QAAAO,CAAA,GAAAK,MAAA,CAAA0B,cAAA,QAAA/B,CAAA,uBAAAR,CAAA,IAAAQ,CAAA,QAAAO,mBAAA,YAAAyB,mBAAAxC,CAAA,EAAAE,CAAA,EAAAE,CAAA,EAAAH,CAAA,aAAAK,EAAAJ,CAAA,EAAAE,CAAA,IAAAW,mBAAA,CAAAf,CAAA,EAAAE,CAAA,YAAAF,CAAA,gBAAAyC,OAAA,CAAAvC,CAAA,EAAAE,CAAA,EAAAJ,CAAA,SAAAE,CAAA,GAAAM,CAAA,GAAAA,CAAA,CAAAR,CAAA,EAAAE,CAAA,IAAA2B,KAAA,EAAAzB,CAAA,EAAAsC,UAAA,GAAAzC,CAAA,EAAA0C,YAAA,GAAA1C,CAAA,EAAA2C,QAAA,GAAA3C,CAAA,MAAAD,CAAA,CAAAE,CAAA,IAAAE,CAAA,IAAAE,CAAA,aAAAA,CAAA,cAAAA,CAAA,mBAAAS,mBAAA,CAAAf,CAAA,EAAAE,CAAA,EAAAE,CAAA,EAAAH,CAAA;AAAA,SAAA4C,mBAAAzC,CAAA,EAAAH,CAAA,EAAAD,CAAA,EAAAE,CAAA,EAAAI,CAAA,EAAAe,CAAA,EAAAZ,CAAA,cAAAD,CAAA,GAAAJ,CAAA,CAAAiB,CAAA,EAAAZ,CAAA,GAAAG,CAAA,GAAAJ,CAAA,CAAAqB,KAAA,WAAAzB,CAAA,gBAAAJ,CAAA,CAAAI,CAAA,KAAAI,CAAA,CAAAoB,IAAA,GAAA3B,CAAA,CAAAW,CAAA,IAAAkC,OAAA,CAAAC,OAAA,CAAAnC,CAAA,EAAAoC,IAAA,CAAA9C,CAAA,EAAAI,CAAA;AAAA,SAAA2C,kBAAA7C,CAAA,6BAAAH,CAAA,SAAAD,CAAA,GAAAkD,SAAA,aAAAJ,OAAA,WAAA5C,CAAA,EAAAI,CAAA,QAAAe,CAAA,GAAAjB,CAAA,CAAA+C,KAAA,CAAAlD,CAAA,EAAAD,CAAA,YAAAoD,MAAAhD,CAAA,IAAAyC,kBAAA,CAAAxB,CAAA,EAAAnB,CAAA,EAAAI,CAAA,EAAA8C,KAAA,EAAAC,MAAA,UAAAjD,CAAA,cAAAiD,OAAAjD,CAAA,IAAAyC,kBAAA,CAAAxB,CAAA,EAAAnB,CAAA,EAAAI,CAAA,EAAA8C,KAAA,EAAAC,MAAA,WAAAjD,CAAA,KAAAgD,KAAA;AAAA,SAAAE,2BAAApD,CAAA,EAAAF,CAAA,QAAAC,CAAA,yBAAAE,MAAA,IAAAD,CAAA,CAAAC,MAAA,CAAAE,QAAA,KAAAH,CAAA,qBAAAD,CAAA,QAAAsD,KAAA,CAAAC,OAAA,CAAAtD,CAAA,MAAAD,CAAA,GAAAwD,2BAAA,CAAAvD,CAAA,MAAAF,CAAA,IAAAE,CAAA,uBAAAA,CAAA,CAAAsB,MAAA,IAAAvB,CAAA,KAAAC,CAAA,GAAAD,CAAA,OAAAyD,EAAA,MAAAC,CAAA,YAAAA,EAAA,eAAAC,CAAA,EAAAD,CAAA,EAAAvD,CAAA,WAAAA,EAAA,WAAAsD,EAAA,IAAAxD,CAAA,CAAAsB,MAAA,KAAAI,IAAA,WAAAA,IAAA,MAAAC,KAAA,EAAA3B,CAAA,CAAAwD,EAAA,UAAA1D,CAAA,WAAAA,EAAAE,CAAA,UAAAA,CAAA,KAAAc,CAAA,EAAA2C,CAAA,gBAAAjC,SAAA,iJAAApB,CAAA,EAAAe,CAAA,OAAAT,CAAA,gBAAAgD,CAAA,WAAAA,EAAA,IAAA3D,CAAA,GAAAA,CAAA,CAAA0B,IAAA,CAAAzB,CAAA,MAAAE,CAAA,WAAAA,EAAA,QAAAF,CAAA,GAAAD,CAAA,CAAA4D,IAAA,WAAAxC,CAAA,GAAAnB,CAAA,CAAA0B,IAAA,EAAA1B,CAAA,KAAAF,CAAA,WAAAA,EAAAE,CAAA,IAAAU,CAAA,OAAAN,CAAA,GAAAJ,CAAA,KAAAc,CAAA,WAAAA,EAAA,UAAAK,CAAA,YAAApB,CAAA,cAAAA,CAAA,8BAAAW,CAAA,QAAAN,CAAA;AAAA,SAAAwD,mBAAA5D,CAAA,WAAA6D,kBAAA,CAAA7D,CAAA,KAAA8D,gBAAA,CAAA9D,CAAA,KAAAuD,2BAAA,CAAAvD,CAAA,KAAA+D,kBAAA;AAAA,SAAAA,mBAAA,cAAAvC,SAAA;AAAA,SAAAsC,iBAAA9D,CAAA,8BAAAC,MAAA,YAAAD,CAAA,CAAAC,MAAA,CAAAE,QAAA,aAAAH,CAAA,uBAAAqD,KAAA,CAAAW,IAAA,CAAAhE,CAAA;AAAA,SAAA6D,mBAAA7D,CAAA,QAAAqD,KAAA,CAAAC,OAAA,CAAAtD,CAAA,UAAAiE,iBAAA,CAAAjE,CAAA;AAAA,SAAAkE,eAAAlE,CAAA,EAAAF,CAAA,WAAAqE,eAAA,CAAAnE,CAAA,KAAAoE,qBAAA,CAAApE,CAAA,EAAAF,CAAA,KAAAyD,2BAAA,CAAAvD,CAAA,EAAAF,CAAA,KAAAuE,gBAAA;AAAA,SAAAA,iBAAA,cAAA7C,SAAA;AAAA,SAAA+B,4BAAAvD,CAAA,EAAAmB,CAAA,QAAAnB,CAAA,2BAAAA,CAAA,SAAAiE,iBAAA,CAAAjE,CAAA,EAAAmB,CAAA,OAAApB,CAAA,MAAAuE,QAAA,CAAA7C,IAAA,CAAAzB,CAAA,EAAAuE,KAAA,6BAAAxE,CAAA,IAAAC,CAAA,CAAAwE,WAAA,KAAAzE,CAAA,GAAAC,CAAA,CAAAwE,WAAA,CAAAC,IAAA,aAAA1E,CAAA,cAAAA,CAAA,GAAAsD,KAAA,CAAAW,IAAA,CAAAhE,CAAA,oBAAAD,CAAA,+CAAA2E,IAAA,CAAA3E,CAAA,IAAAkE,iBAAA,CAAAjE,CAAA,EAAAmB,CAAA;AAAA,SAAA8C,kBAAAjE,CAAA,EAAAmB,CAAA,aAAAA,CAAA,IAAAA,CAAA,GAAAnB,CAAA,CAAAsB,MAAA,MAAAH,CAAA,GAAAnB,CAAA,CAAAsB,MAAA,YAAAxB,CAAA,MAAAI,CAAA,GAAAmD,KAAA,CAAAlC,CAAA,GAAArB,CAAA,GAAAqB,CAAA,EAAArB,CAAA,IAAAI,CAAA,CAAAJ,CAAA,IAAAE,CAAA,CAAAF,CAAA,UAAAI,CAAA;AAAA,SAAAkE,sBAAApE,CAAA,EAAAuB,CAAA,QAAAxB,CAAA,WAAAC,CAAA,gCAAAC,MAAA,IAAAD,CAAA,CAAAC,MAAA,CAAAE,QAAA,KAAAH,CAAA,4BAAAD,CAAA,QAAAD,CAAA,EAAAI,CAAA,EAAAI,CAAA,EAAAI,CAAA,EAAAS,CAAA,OAAAL,CAAA,OAAAV,CAAA,iBAAAE,CAAA,IAAAP,CAAA,GAAAA,CAAA,CAAA0B,IAAA,CAAAzB,CAAA,GAAA2D,IAAA,QAAApC,CAAA,QAAAZ,MAAA,CAAAZ,CAAA,MAAAA,CAAA,UAAAe,CAAA,uBAAAA,CAAA,IAAAhB,CAAA,GAAAQ,CAAA,CAAAmB,IAAA,CAAA1B,CAAA,GAAA2B,IAAA,MAAAP,CAAA,CAAAwD,IAAA,CAAA7E,CAAA,CAAA6B,KAAA,GAAAR,CAAA,CAAAG,MAAA,KAAAC,CAAA,GAAAT,CAAA,iBAAAd,CAAA,IAAAI,CAAA,OAAAF,CAAA,GAAAF,CAAA,yBAAAc,CAAA,YAAAf,CAAA,eAAAW,CAAA,GAAAX,CAAA,cAAAY,MAAA,CAAAD,CAAA,MAAAA,CAAA,2BAAAN,CAAA,QAAAF,CAAA,aAAAiB,CAAA;AAAA,SAAAgD,gBAAAnE,CAAA,QAAAqD,KAAA,CAAAC,OAAA,CAAAtD,CAAA,UAAAA,CAAA;AAAA,SAAA4E,QAAAxE,CAAA,sCAAAwE,OAAA,wBAAA3E,MAAA,uBAAAA,MAAA,CAAAE,QAAA,aAAAC,CAAA,kBAAAA,CAAA,gBAAAA,CAAA,WAAAA,CAAA,yBAAAH,MAAA,IAAAG,CAAA,CAAAoE,WAAA,KAAAvE,MAAA,IAAAG,CAAA,KAAAH,MAAA,CAAAO,SAAA,qBAAAJ,CAAA,KAAAwE,OAAA,CAAAxE,CAAA;AADAyE,MAAM,CAACC,iBAAiB,GAAG,YAAY;EAEnC;EACA,IAAIC,aAAa,GAAG;IAChB;IACAC,qBAAqB,EAAE,iBAAiB;IACxCC,sBAAsB,EAAE,GAAG;IAC3BC,kBAAkB,EAAE,gBAAgB;IACpCC,kBAAkB,EAAE,yBAAyB;IAC7CC,uBAAuB,EAAE,UAAU;IACnCC,SAAS,EAAE,KAAK;IAChBC,cAAc,EAAE,WAAW;IAC3BC,aAAa,EAAE,WAAW;IAC1BC,eAAe,EAAE,aAAa;IAC9BC,SAAS,EAAE,2CAA2C;IACtDC,cAAc,EAAE,SAAS;IACzBC,MAAM,EAAE;MACJC,mBAAmB,EAAE,IAAI;MACzBC,mBAAmB,EAAE,IAAI;MACzBC,kBAAkB,EAAE,IAAI;MACxBC,iBAAiB,EAAE,IAAI;MACvBC,kBAAkB,EAAE,IAAI;MACxBC,aAAa,EAAE,IAAI;MACnBC,oBAAoB,EAAE,IAAI;MAC1BC,uBAAuB,EAAE,IAAI;MAC7BC,kBAAkB,EAAE,wBAAwB;MAC5CC,cAAc,EAAE,IAAI;MACpBC,cAAc,EAAE,IAAI;MACpBC,aAAa,EAAE,IAAI;MACnBC,YAAY,EAAE,IAAI;MAClBC,aAAa,EAAE,IAAI;MACnBC,QAAQ,EAAE,GAAG;MACbC,SAAS,EAAE;IACf,CAAC;IACDC,eAAe,2tIAiDlB;IACGC,iBAAiB;EAMrB,CAAC;;EAED;EACA,SAASC,WAAWA,CAACC,GAAG,EAAE;IACtB,IAAI,CAACA,GAAG,EAAE,OAAO,EAAE;IACnB,IAAIC,OAAO,GAAGD,GAAG,CAACE,IAAI,CAAC,CAAC;IACxB,IAAI,eAAe,CAACvC,IAAI,CAACsC,OAAO,CAAC,IAAI,aAAa,CAACtC,IAAI,CAACsC,OAAO,CAAC,IAAI,mBAAmB,CAACtC,IAAI,CAACsC,OAAO,CAAC,EAAE;MACnG,OAAO,EAAE;IACb;IACA,OAAOD,GAAG;EACd;;EAEA;EACA,SAASG,kBAAkBA,CAACC,IAAI,EAAE;IAC9B,IAAIC,IAAI,GAAGC,QAAQ,CAACC,aAAa,CAAC,MAAM,CAAC;IACzCF,IAAI,CAACG,WAAW,GAAGJ,IAAI;IACvB,OAAOC,IAAI,CAACI,SAAS;EACzB;EAEA,SAASC,eAAeA,CAAC9F,KAAK,EAAE;IAC5B,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI+F,MAAM,CAACC,QAAQ,CAAChG,KAAK,CAAC,EAAE;MACrD,OAAOA,KAAK;IAChB;IAEA,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;MAC3B,OAAO,IAAI;IACf;IAEA,IAAIiG,MAAM,GAAGC,UAAU,CAAClG,KAAK,CAAC;IAC9B,OAAO+F,MAAM,CAACC,QAAQ,CAACC,MAAM,CAAC,GAAGA,MAAM,GAAG,IAAI;EAClD;EAEA,SAASE,KAAKA,CAACnG,KAAK,EAAEoG,GAAG,EAAEC,GAAG,EAAE;IAC5B,OAAOC,IAAI,CAACF,GAAG,CAACE,IAAI,CAACD,GAAG,CAACrG,KAAK,EAAEoG,GAAG,CAAC,EAAEC,GAAG,CAAC;EAC9C;EAEA,SAASE,kBAAkBA,CAACC,SAAS,EAAE;IAAA,IAAAC,IAAA,EAAAC,iBAAA,EAAAC,KAAA,EAAAC,gBAAA,EAAAC,KAAA,EAAAC,gBAAA;IACnC,IAAI,CAACN,SAAS,IAAIvD,OAAA,CAAOuD,SAAS,MAAK,QAAQ,EAAE;MAC7C,OAAO,IAAI;IACf;IAEA,IAAMO,UAAU,GAAG/H,MAAM,CAACgI,MAAM,CAAC,CAAC,CAAC,EAAER,SAAS,CAAC;IAC/CO,UAAU,CAACE,KAAK,IAAAR,IAAA,IAAAC,iBAAA,GAAGK,UAAU,CAACE,KAAK,cAAAP,iBAAA,cAAAA,iBAAA,GAAIK,UAAU,CAACG,KAAK,cAAAT,IAAA,cAAAA,IAAA,GAAI,CAAC;IAC5DM,UAAU,CAACvB,IAAI,IAAAmB,KAAA,IAAAC,gBAAA,GAAGG,UAAU,CAACvB,IAAI,cAAAoB,gBAAA,cAAAA,gBAAA,GAAIG,UAAU,CAACI,IAAI,cAAAR,KAAA,cAAAA,KAAA,GAAI,IAAI;IAC5DI,UAAU,CAACK,IAAI,IAAAP,KAAA,IAAAC,gBAAA,GAAGC,UAAU,CAACK,IAAI,cAAAN,gBAAA,cAAAA,gBAAA,GAAIC,UAAU,CAACM,IAAI,cAAAR,KAAA,cAAAA,KAAA,GAAI,IAAI;IAE5D,OAAOE,UAAU;EACrB;EAEA,SAASO,mBAAmBA,CAACC,UAAU,EAAE;IACrC,IAAI,CAACA,UAAU,IAAItE,OAAA,CAAOsE,UAAU,MAAK,QAAQ,EAAE;MAC/C,OAAO,CAAC,CAAC;IACb;IAEA,IAAMR,UAAU,GAAG,CAAC,CAAC;IAErB,SAAAS,EAAA,MAAAC,eAAA,GAA2BzI,MAAM,CAAC0I,OAAO,CAACH,UAAU,CAAC,EAAAC,EAAA,GAAAC,eAAA,CAAA9H,MAAA,EAAA6H,EAAA,IAAE;MAAA,IAAAG,mBAAA;MAAlD,IAAAC,kBAAA,GAAArF,cAAA,CAAAkF,eAAA,CAAAD,EAAA;QAAOK,GAAG,GAAAD,kBAAA;QAAE5H,KAAK,GAAA4H,kBAAA;MAClBb,UAAU,CAACc,GAAG,CAAC,IAAAF,mBAAA,GAAGpB,kBAAkB,CAACvG,KAAK,CAAC,cAAA2H,mBAAA,cAAAA,mBAAA,GAAI,CAAC,CAAC;IACrD;IAEA,OAAOZ,UAAU;EACrB;EAEA,IAAMe,QAAQ,GAAG,IAAIC,MAAM,CAACC,QAAQ,CAAC,CAAC;;EAEtC;EACAF,QAAQ,CAACV,IAAI,GAAG,UAAUa,IAAI,EAAE;IAC5B,IAAIC,IAAI,GAAG/C,WAAW,CAAC8C,IAAI,CAACC,IAAI,CAAC;IACjC,IAAI,CAACA,IAAI,EAAE,OAAOD,IAAI,CAACzC,IAAI,IAAI,EAAE;IACjC,oBAAA2C,MAAA,CAAmBD,IAAI,uDAAAC,MAAA,CAA+CF,IAAI,CAACzC,IAAI;EACnF,CAAC;;EAED;EACAsC,QAAQ,CAACM,IAAI,GAAG,UAAUH,IAAI,EAAE;IAC5B,IAAIG,IAAI,GAAGH,IAAI,CAACzC,IAAI,IAAI,EAAE;IAC1B,IAAI6C,IAAI,GAAG,CAACJ,IAAI,CAACI,IAAI,IAAI,EAAE,EAAE/C,IAAI,CAAC,CAAC;IACnC,IAAIgD,WAAW,GAAGF,IAAI;IAEtB,IAAI,OAAOG,IAAI,KAAK,WAAW,EAAE;MAC7B,IAAIF,IAAI,IAAIE,IAAI,CAACC,WAAW,CAACH,IAAI,CAAC,EAAE;QAChC,IAAI;UACAC,WAAW,GAAGC,IAAI,CAACE,SAAS,CAACL,IAAI,EAAE;YAAEM,QAAQ,EAAEL;UAAK,CAAC,CAAC,CAACrI,KAAK;QAChE,CAAC,CAAC,OAAO2I,CAAC,EAAE,CAAE;MAClB,CAAC,MAAM;QACH,IAAI;UACAL,WAAW,GAAGC,IAAI,CAACK,aAAa,CAACR,IAAI,CAAC,CAACpI,KAAK;QAChD,CAAC,CAAC,OAAO2I,CAAC,EAAE,CAAE;MAClB;IACJ,CAAC,MAAM;MACHL,WAAW,GAAG/C,kBAAkB,CAAC6C,IAAI,CAAC;IAC1C;IAEA,IAAIS,WAAW,GAAGR,IAAI,GAAG9C,kBAAkB,CAAC8C,IAAI,CAAC,GAAG,MAAM;IAC1D,qIAAAF,MAAA,CAA6HU,WAAW,8JAAAV,MAAA,CAAkJE,IAAI,GAAG,YAAY,GAAGA,IAAI,GAAG,EAAE,SAAAF,MAAA,CAAKG,WAAW;EAC7U,CAAC;;EAED;EACA;EACAR,QAAQ,CAACgB,KAAK,GAAG,UAAUb,IAAI,EAAE;IAC7B,IAAMc,GAAG,GAAG5D,WAAW,CAAC8C,IAAI,CAACC,IAAI,CAAC;IAClC,IAAI,CAACa,GAAG,EAAE,OAAO,EAAE;IACnB,IAAMC,GAAG,GAAGf,IAAI,CAACzC,IAAI,IAAIpC,aAAa,CAACC,qBAAqB;IAC5D,IAAM4F,QAAQ,GAAG7F,aAAa,CAACE,sBAAsB;IACrD,wEAAA6E,MAAA,CACYY,GAAG,eAAAZ,MAAA,CAAUa,GAAG,oDAAAb,MAAA,CAA6Cc,QAAQ,kFAAAd,MAAA,CAElEY,GAAG,sCAAAZ,MAAA,CAA+Ba,GAAG,iBAAAb,MAAA,CAAY/E,aAAa,CAACG,kBAAkB;EAKpG,CAAC;;EAED;EACA,IAAI2F,YAAY,GAAG,CAAC;;EAEpB;EACA,IAAIC,cAAc,GAAG,EAAE;;EAEvB;EACA;EACA;EACAjG,MAAM,CAACkG,cAAc,GAAGlG,MAAM,CAACkG,cAAc,IAAI,CAAC,CAAC;EAEnD,SAASC,eAAeA,CAACC,OAAO,EAAE;IAC9B,OAAO,oIAAAnB,MAAA,CACcmB,OAAO,iBAAa,WAC3B,yBACY,4GAAAnB,MAAA,CACgFmB,OAAO,iBAAAnB,MAAA,CAAY/E,aAAa,CAACI,kBAAkB,QAAI,6CAAA2E,MAAA,CACnH/E,aAAa,CAACK,uBAAuB,CAAE,cACpE,WACH;EAClB;;EAEA;EACA;EACAsE,MAAM,CAACwB,GAAG,CAAC;IACPC,UAAU,EAAE,CAAC;MACT1G,IAAI,EAAE,OAAO;MACb2G,KAAK,EAAE,OAAO;MACdC,KAAK,WAALA,KAAKA,CAACX,GAAG,EAAE;QACP,IAAMY,GAAG,GAAGZ,GAAG,CAACa,OAAO,CAAC,SAAS,CAAC;QAClC,OAAOD,GAAG,IAAI,CAAC,GAAGA,GAAG,GAAGE,SAAS;MACrC,CAAC;MACDC,SAAS,WAATA,SAASA,CAACf,GAAG,EAAE;QACX,IAAMgB,SAAS,GAAGC,qBAAqB,CAACjB,GAAG,CAAC;QAC5C,IAAI,CAACgB,SAAS,IAAIA,SAAS,CAACE,UAAU,KAAK,CAAC,EAAE;UAC1C,OAAOJ,SAAS;QACpB;QAEA,IAAMP,OAAO,iBAAAnB,MAAA,CAAiB,EAAEe,YAAY,CAAE;QAE9C,OAAO;UACHgB,IAAI,EAAE,OAAO;UACbC,GAAG,EAAEpB,GAAG,CAACqB,SAAS,CAAC,CAAC,EAAEL,SAAS,CAACM,QAAQ,CAAC;UACzCf,OAAO,EAAEA,OAAO;UAChBgB,IAAI,EAAEP,SAAS,CAACO;QACpB,CAAC;MACL,CAAC;MACDxC,QAAQ,WAARA,QAAQA,CAACyC,KAAK,EAAE;QACZpB,cAAc,CAACnG,IAAI,CAAC;UAAEsG,OAAO,EAAEiB,KAAK,CAACjB,OAAO;UAAEkB,MAAM,EAAED,KAAK,CAACD;QAAK,CAAC,CAAC;QACnEpH,MAAM,CAACkG,cAAc,CAACmB,KAAK,CAACjB,OAAO,CAAC,GAAGiB,KAAK,CAACD,IAAI;QACjD,OAAOjB,eAAe,CAACkB,KAAK,CAACjB,OAAO,CAAC;MACzC;IACJ,CAAC;EACL,CAAC,CAAC;;EAEF;EACA,SAASU,qBAAqBA,CAACxE,IAAI,EAAE;IACjC,IAAM+E,KAAK,GAAG,SAAS;IACvB,IAAMb,KAAK,GAAGlE,IAAI,CAACoE,OAAO,CAACW,KAAK,CAAC;IACjC,IAAIb,KAAK,GAAG,CAAC,EAAE;MACX,OAAO,IAAI;IACf;;IAEA;IACA,IAAMe,SAAS,GAAGf,KAAK,GAAGa,KAAK,CAAC5K,MAAM;IACtC,IAAIhB,CAAC,GAAG8L,SAAS;IACjB,OAAO9L,CAAC,GAAG6G,IAAI,CAAC7F,MAAM,KAAK6F,IAAI,CAAC7G,CAAC,CAAC,KAAK,GAAG,IAAI6G,IAAI,CAAC7G,CAAC,CAAC,KAAK,IAAI,IAAI6G,IAAI,CAAC7G,CAAC,CAAC,KAAK,IAAI,IAAI6G,IAAI,CAAC7G,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE;MACrGA,CAAC,EAAE;IACP;IAEA,IAAIA,CAAC,IAAI6G,IAAI,CAAC7F,MAAM,IAAI6F,IAAI,CAAC7G,CAAC,CAAC,KAAK,GAAG,EAAE;MACrC,OAAO,IAAI;IACf;IAEA,IAAI+L,KAAK,GAAG,CAAC;IACb,IAAIC,QAAQ,GAAG,KAAK;IACpB,IAAIC,MAAM,GAAG,KAAK;IAElB,OAAOjM,CAAC,GAAG6G,IAAI,CAAC7F,MAAM,EAAEhB,CAAC,EAAE,EAAE;MACzB,IAAMkM,EAAE,GAAGrF,IAAI,CAAC7G,CAAC,CAAC;MAElB,IAAIgM,QAAQ,EAAE;QACV,IAAIC,MAAM,EAAE;UACRA,MAAM,GAAG,KAAK;UACd;QACJ;QACA,IAAIC,EAAE,KAAK,IAAI,EAAE;UACbD,MAAM,GAAG,IAAI;UACb;QACJ;QACA,IAAIC,EAAE,KAAK,GAAG,EAAE;UACZF,QAAQ,GAAG,KAAK;QACpB;QACA;MACJ;MAEA,IAAIE,EAAE,KAAK,GAAG,EAAE;QACZF,QAAQ,GAAG,IAAI;QACf;MACJ;MAEA,IAAIE,EAAE,KAAK,GAAG,EAAE;QACZH,KAAK,EAAE;MACX,CAAC,MAAM,IAAIG,EAAE,KAAK,GAAG,EAAE;QACnBH,KAAK,EAAE;QACP,IAAIA,KAAK,KAAK,CAAC,EAAE;UACb,IAAMI,OAAO,GAAGnM,CAAC;UACjB;UACA,IAAMoM,iBAAiB,GAAGvF,IAAI,CAACoE,OAAO,CAAC,GAAG,EAAEkB,OAAO,GAAG,CAAC,CAAC;UACxD,IAAIC,iBAAiB,GAAG,CAAC,EAAE;YACvB,OAAO,IAAI;UACf;UAEA,IAAMT,IAAI,GAAG9E,IAAI,CAAC4E,SAAS,CAACK,SAAS,EAAEK,OAAO,GAAG,CAAC,CAAC,CAACxF,IAAI,CAAC,CAAC;UAC1D,OAAO;YACH2E,UAAU,EAAEP,KAAK;YACjBW,QAAQ,EAAEU,iBAAiB,GAAG,CAAC;YAC/BT,IAAI,EAAEA;UACV,CAAC;QACL;MACJ;IACJ;IAEA,OAAO,IAAI;EACf;EAEA,SAASU,qBAAqBA,CAACC,OAAO,EAAE;IACpC,IAAI,CAACA,OAAO,IAAI,CAACA,OAAO,CAAC9B,cAAc,IAAI,CAAC8B,OAAO,CAAC9B,cAAc,CAACxJ,MAAM,EAAE;MACvE;IACJ;;IAEA;IACA,IAAMuL,MAAM,GAAAjJ,kBAAA,CAAOgJ,OAAO,CAAC9B,cAAc,CAAC;IAC1C8B,OAAO,CAAC9B,cAAc,GAAG,EAAE;;IAE3B;IACA;IACAgC,qBAAqB,CAAC,YAAM;MAAA,IAAAC,SAAA,GAAA3J,0BAAA,CACRyJ,MAAM;QAAAG,KAAA;MAAA;QAAtB,KAAAD,SAAA,CAAArJ,CAAA,MAAAsJ,KAAA,GAAAD,SAAA,CAAA7M,CAAA,IAAAwB,IAAA,GAAwB;UAAA,IAAbnB,CAAC,GAAAyM,KAAA,CAAArL,KAAA;UACRsL,mBAAmB,CAAC1M,CAAC,CAAC0K,OAAO,EAAE1K,CAAC,CAAC4L,MAAM,CAAC;QAC5C;MAAC,SAAAe,GAAA;QAAAH,SAAA,CAAAjN,CAAA,CAAAoN,GAAA;MAAA;QAAAH,SAAA,CAAAjM,CAAA;MAAA;IACL,CAAC,CAAC;EACN;EAEA,SAASmM,mBAAmBA,CAAChC,OAAO,EAAEkB,MAAM,EAAE;IAC1C,IAAMgB,MAAM,GAAG9F,QAAQ,CAAC+F,cAAc,CAACnC,OAAO,CAAC;IAC/C,IAAI,CAACkC,MAAM,EAAE;MACT,OAAO,KAAK;IAChB;IAEA,IAAI,OAAOE,KAAK,KAAK,WAAW,EAAE;MAC9BC,OAAO,CAACC,IAAI,CAAC,+LAA+L,CAAC;MAC7M,OAAO,KAAK;IAChB;;IAEA;IACA;IACA;IACA;IACA,IAAIJ,MAAM,CAACK,YAAY,KAAK,IAAI,EAAE;MAC9B3I,MAAM,CAACkG,cAAc,CAACE,OAAO,CAAC,GAAGkB,MAAM;MACvC,OAAO,KAAK;IAChB;IAEA,IAAI;MAAA,IAAAsB,YAAA,EAAAC,aAAA,EAAAC,qBAAA;MACA,IAAIR,MAAM,CAACS,cAAc,EAAE;QACvBT,MAAM,CAACS,cAAc,CAACC,OAAO,CAAC,CAAC;MACnC;MAEA,IAAMC,GAAG,GAAG,OAAO3B,MAAM,KAAK,QAAQ,GAAG4B,IAAI,CAACC,KAAK,CAAC7B,MAAM,CAAC,GAAGA,MAAM;MACpE,CAAAsB,YAAA,GAAAK,GAAG,CAACG,OAAO,cAAAR,YAAA,cAAAA,YAAA,GAAXK,GAAG,CAACG,OAAO,GAAK,CAAC,CAAC;MAClBH,GAAG,CAACG,OAAO,CAACC,UAAU,GAAG,IAAI;MAC7BJ,GAAG,CAACG,OAAO,CAACE,mBAAmB,GAAG,IAAI;MACtC,CAAAR,qBAAA,IAAAD,aAAA,GAAAI,GAAG,CAACG,OAAO,EAACG,WAAW,cAAAT,qBAAA,cAAAA,qBAAA,GAAvBD,aAAA,CAAYU,WAAW,GAAK,CAAC,GAAG,CAAC;MAEjCjB,MAAM,CAACS,cAAc,GAAG,IAAIP,KAAK,CAACF,MAAM,EAAEW,GAAG,CAAC;MAC9C,OAAOjJ,MAAM,CAACkG,cAAc,CAACE,OAAO,CAAC;MACrC,OAAO,IAAI;IACf,CAAC,CAAC,OAAOnL,CAAC,EAAE;MACRwN,OAAO,CAACe,KAAK,CAAC,uBAAuB,EAAEvO,CAAC,CAAC;MACzC,OAAO,KAAK;IAChB;EACJ;;EAEA;EACA;EACA;EACA+E,MAAM,CAACyJ,mBAAmB,GAAG,YAAY;IACrC,IAAI,OAAOjB,KAAK,KAAK,WAAW,EAAE;MAC9B;IACJ;IAEA,IAAMkB,OAAO,GAAG1J,MAAM,CAACkG,cAAc;IACrC,IAAI,CAACwD,OAAO,EAAE;MACV;IACJ;IAEAzB,qBAAqB,CAAC,YAAM;MACxB,SAAA0B,GAAA,MAAAC,YAAA,GAAsB9N,MAAM,CAAC+N,IAAI,CAACH,OAAO,CAAC,EAAAC,GAAA,GAAAC,YAAA,CAAAnN,MAAA,EAAAkN,GAAA,IAAE;QAAvC,IAAMvD,OAAO,GAAAwD,YAAA,CAAAD,GAAA;QACdvB,mBAAmB,CAAChC,OAAO,EAAEsD,OAAO,CAACtD,OAAO,CAAC,CAAC;MAClD;IACJ,CAAC,CAAC;EACN,CAAC;;EAED;EACA;EACA;EACA,SAAS0D,oBAAoBA,CAACC,OAAO,EAAEhC,OAAO,EAAE;IAC5C9B,cAAc,GAAG,EAAE;IACnB,IAAM+D,IAAI,GAAGnF,MAAM,CAACsE,KAAK,CAACY,OAAO,EAAE;MAAEnF,QAAQ,EAARA;IAAS,CAAC,CAAC;IAChDmD,OAAO,CAAC9B,cAAc,GAAGA,cAAc,CAACxJ,MAAM,GAAG,CAAC,GAAAsC,kBAAA,CAAOkH,cAAc,IAAI,EAAE;IAC7E,OAAOgE,SAAS,CAACC,QAAQ,CAACF,IAAI,EAAE;MAAEG,QAAQ,EAAE,CAAC,QAAQ,CAAC;MAAEC,QAAQ,EAAE,CAAC,QAAQ;IAAE,CAAC,CAAC;EACnF;EAEA,IAAMC,UAAU,GAAG,SAAbA,UAAUA,CAAIC,cAAc,EAAK;IAEnC,IAAMhD,MAAM,GAAGxL,MAAM,CAACgI,MAAM,CAAC,CAAC,CAAC,EAAE5D,aAAa,EAAEoK,cAAc,CAAC;IAC/DhD,MAAM,CAACxG,MAAM,GAAGhF,MAAM,CAACgI,MAAM,CAAC,CAAC,CAAC,EAAE5D,aAAa,CAACY,MAAM,IAAI,CAAC,CAAC,EAAEwJ,cAAc,IAAIA,cAAc,CAACxJ,MAAM,GAAGwJ,cAAc,CAACxJ,MAAM,GAAG,CAAC,CAAC,CAAC;IACnI,IAAMyJ,eAAe,GAAG,CAAC,EAAED,cAAc,IAAIA,cAAc,CAACxJ,MAAM,IAAIwJ,cAAc,CAACxJ,MAAM,CAACC,mBAAmB,IAAIuJ,cAAc,CAACxJ,MAAM,CAACE,mBAAmB,CAAC;IAC7J;IACAd,aAAa,GAAGoH,MAAM;IAEtB,IAAI,CAACA,MAAM,CAACkD,aAAa,EAAE;MACvB/B,OAAO,CAACe,KAAK,CAAC,gCAAgC,CAAC;MAC/C;IACJ;IAEA,IAAI,CAAClC,MAAM,CAACmD,kBAAkB,EAAE;MAC5BhC,OAAO,CAACe,KAAK,CAAC,qCAAqC,CAAC;MACpD;IACJ;IAEA,IAAI,CAAClC,MAAM,CAACoD,4BAA4B,EAAE;MACtCjC,OAAO,CAACe,KAAK,CAAC,+CAA+C,CAAC;MAC9D;IACJ;IAEA,IAAI,CAAClC,MAAM,CAACqD,oBAAoB,EAAE;MAC9BlC,OAAO,CAACe,KAAK,CAAC,uCAAuC,CAAC;MACtD;IACJ;IAEA,IAAI,CAAClC,MAAM,CAACsD,yBAAyB,EAAE;MACnCnC,OAAO,CAACe,KAAK,CAAC,4CAA4C,CAAC;MAC3D;IACJ;IAEA,IAAMqB,GAAG,GAAGC,GAAG,CAACC,SAAS,CAAC;MACtBhG,IAAI,WAAJA,IAAIA,CAAA,EAAG;QACH,OAAO;UACHiG,YAAY,EAAE,IAAI;UAClBC,aAAa,EAAE,IAAI;UACnBC,aAAa,EAAE,IAAI;UACnBC,WAAW,EAAE,IAAI;UACjBC,gBAAgB,EAAE,KAAK;UACvBC,oBAAoB,EAAE,IAAI;UAC1BrK,mBAAmB,EAAE,IAAI;UACzBsK,sBAAsB,EAAE,IAAI;UAC5BC,mBAAmB,EAAE,IAAI;UACzBtK,kBAAkB,EAAE,IAAI;UACxBuK,sBAAsB,EAAE,IAAI;UAC5BC,yBAAyB,EAAE,IAAI;UAC/BC,4BAA4B,EAAE,IAAI;UAClCC,oBAAoB,EAAE,IAAI;UAC1BC,2BAA2B,EAAE,IAAI;UACjCC,kBAAkB,EAAE,IAAI;UACxBC,mBAAmB,EAAE,IAAI;UACzBC,mBAAmB,EAAE,KAAK;UAC1BC,WAAW,EAAE,KAAK;UAClBC,gBAAgB,EAAE,KAAK;UACvBC,UAAU,EAAE,IAAI;UAChBC,MAAM,EAAE,IAAI;UACZC,QAAQ,EAAE,EAAE;UACZC,aAAa,EAAE,EAAE;UACjBC,MAAM,EAAE,EAAE;UACVC,SAAS,EAAEjF,MAAM,CAACkF,iBAAiB,IAAI,EAAE;UACzCC,WAAW,EAAE,KAAK;UAClBC,YAAY,EAAE,EAAE;UAChBC,UAAU,EAAE,KAAK;UACjBC,WAAW,EAAE,IAAI;UACjBC,cAAc,EAAE,CAAC,CAACvF,MAAM,CAACuF,cAAc;UACvCrM,SAAS,EAAE8G,MAAM,CAAC9G,SAAS;UAC3BC,cAAc,EAAE6G,MAAM,CAAC7G,cAAc;UACrCC,aAAa,EAAE4G,MAAM,CAAC5G,aAAa;UACnCC,eAAe,EAAE2G,MAAM,CAAC3G,eAAe;UACvCC,SAAS,EAAE0G,MAAM,CAAC1G,SAAS;UAC3BkM,WAAW,EAAE,KAAK;UAClBC,aAAa,EAAE,IAAI;UACnBC,kBAAkB,EAAE,EAAE;UACtBC,SAAS,EAAE,IAAI;UACfC,mBAAmB,EAAE5F,MAAM,CAAC6F,QAAQ,KAAK,YAAY,IAAI7F,MAAM,CAAC6F,QAAQ,KAAK,cAAc;UAC3FC,mBAAmB,EAAE9F,MAAM,CAAC6F,QAAQ,KAAK,cAAc,IAAI,CAAC,CAAC7F,MAAM,CAAC8F,mBAAmB;UACvFC,YAAY,EAAE/F,MAAM,CAAC+F,YAAY,IAAI,IAAI;UACzCC,WAAW,EAAE,EAAE;UACfC,cAAc,EAAE,EAAE;UAClBC,cAAc,EAAE,KAAK;UACrBC,mBAAmB,EAAE,IAAI;UACzBC,eAAe,EAAE,IAAI;UACrBC,SAAS,EAAE,IAAI;UACfC,sBAAsB,EAAE,CAAC,CAAC;UAC1BC,aAAa,EAAE,CAAC,CAAC;UACjBC,aAAa,EAAE,UAAU,GAAG1K,IAAI,CAAC2K,MAAM,CAAC,CAAC,CAACtO,QAAQ,CAAC,EAAE,CAAC,CAACC,KAAK,CAAC,CAAC,CAAC;UAC/DsO,kBAAkB,EAAE,CAAC,CAAC1G,MAAM,CAAC0G,kBAAkB;UAC/CC,uBAAuB,EAAE3G,MAAM,CAAC6F,QAAQ,KAAK,cAAc;UAC3De,kBAAkB,EAAE,IAAI;UACxBC,kBAAkB,EAAE,KAAK;UACzBC,yBAAyB,EAAE,CAAC;QAChC,CAAC;MACL,CAAC;MACDC,QAAQ,EAAE;QACNC,kBAAkB,WAAlBA,kBAAkBA,CAAA,EAAG;UACjB,KAAK,IAAI7S,CAAC,GAAG,IAAI,CAAC2Q,QAAQ,CAAC3P,MAAM,GAAG,CAAC,EAAEhB,CAAC,IAAI,CAAC,EAAEA,CAAC,EAAE,EAAE;YAChD,IAAI,IAAI,CAAC2Q,QAAQ,CAAC3Q,CAAC,CAAC,CAAC8S,IAAI,KAAK,WAAW,EAAE;cACvC,OAAO9S,CAAC;YACZ;UACJ;UACA,OAAO,CAAC,CAAC;QACb;MACJ,CAAC;MACD+S,OAAO,EAAE;QACLC,kBAAkB,WAAlBA,kBAAkBA,CAAA,EAAG;UACjB,IAAI,CAACxC,gBAAgB,GAAG,IAAI;QAChC,CAAC;QACDyC,qBAAqB,WAArBA,qBAAqBA,CAAA,EAAG;UACpB,IAAI,CAAC,IAAI,CAACnD,mBAAmB,IAAI,CAACjE,MAAM,CAACxG,MAAM,CAACY,aAAa,EAAE;YAC3D,OAAO,CAAC,CAAC;UACb;UAEA,IAAI;YACA,IAAIiN,YAAY,GAAGC,YAAY,CAACC,OAAO,CAAC,IAAI,CAACtD,mBAAmB,CAAC;YACjE,OAAOoD,YAAY,GAAGzF,IAAI,CAACC,KAAK,CAACwF,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;UAC7D,CAAC,CAAC,OAAOnF,KAAK,EAAE;YACZf,OAAO,CAACC,IAAI,CAAC,qCAAqC,EAAEc,KAAK,CAAC;YAC1D,OAAO,CAAC,CAAC;UACb;QACJ,CAAC;QACDsF,sBAAsB,WAAtBA,sBAAsBA,CAACC,aAAa,EAAE;UAClC,IAAI,CAAC,IAAI,CAACxD,mBAAmB,IAAI,CAACjE,MAAM,CAACxG,MAAM,CAACY,aAAa,EAAE;YAC3D;UACJ;UAEA,IAAIsN,aAAa,GAAG,IAAI,CAACN,qBAAqB,CAAC,CAAC;UAChD,IAAIO,UAAU,GAAGnT,MAAM,CAACgI,MAAM,CAAC,CAAC,CAAC,EAAEkL,aAAa,CAAC;UAEjD,IAAID,aAAa,CAACG,KAAK,KAAKvI,SAAS,EAAE;YACnCsI,UAAU,CAACC,KAAK,GAAGpT,MAAM,CAACgI,MAAM,CAAC,CAAC,CAAC,EAAEkL,aAAa,CAACE,KAAK,IAAI,CAAC,CAAC,EAAEH,aAAa,CAACG,KAAK,IAAI,CAAC,CAAC,CAAC;UAC9F;UAEA,IAAIH,aAAa,CAACI,MAAM,KAAKxI,SAAS,EAAE;YACpCsI,UAAU,CAACE,MAAM,GAAGrT,MAAM,CAACgI,MAAM,CAAC,CAAC,CAAC,EAAEkL,aAAa,CAACG,MAAM,IAAI,CAAC,CAAC,EAAEJ,aAAa,CAACI,MAAM,IAAI,CAAC,CAAC,CAAC;UACjG;UAEAP,YAAY,CAACQ,OAAO,CAAC,IAAI,CAAC7D,mBAAmB,EAAErC,IAAI,CAACmG,SAAS,CAACJ,UAAU,CAAC,CAAC;QAC9E,CAAC;QACDK,cAAc,WAAdA,cAAcA,CAACC,OAAO,EAAEC,aAAa,EAAEC,cAAc,EAAE;UACnD,IAAI,CAACF,OAAO,EAAE;YACV,OAAO;cACHG,KAAK,EAAEF,aAAa,IAAI,CAAC;cACzBG,MAAM,EAAEF,cAAc,IAAI;YAC9B,CAAC;UACL;UAEA,IAAIG,IAAI,GAAGL,OAAO,CAACM,qBAAqB,CAAC,CAAC;UAC1C,IAAIxB,QAAQ,GAAGrO,MAAM,CAAC8P,gBAAgB,CAACP,OAAO,CAAC;UAE/C,OAAO;YACHG,KAAK,EAAEtM,IAAI,CAAC2M,KAAK,CAACH,IAAI,CAACF,KAAK,IAAI9M,eAAe,CAACyL,QAAQ,CAACqB,KAAK,CAAC,IAAIF,aAAa,IAAI,CAAC,CAAC;YACtFG,MAAM,EAAEvM,IAAI,CAAC2M,KAAK,CAACH,IAAI,CAACD,MAAM,IAAI/M,eAAe,CAACyL,QAAQ,CAACsB,MAAM,CAAC,IAAIF,cAAc,IAAI,CAAC;UAC7F,CAAC;QACL,CAAC;QACDO,mBAAmB,WAAnBA,mBAAmBA,CAACC,IAAI,EAAEC,GAAG,EAAER,KAAK,EAAEC,MAAM,EAAE;UAC1C,IAAIQ,eAAe,GAAG,CAAC;UACvB,IAAIC,OAAO,GAAGhN,IAAI,CAACD,GAAG,CAACgN,eAAe,EAAEnQ,MAAM,CAACqQ,UAAU,GAAGX,KAAK,GAAGS,eAAe,CAAC;UACpF,IAAIG,MAAM,GAAGlN,IAAI,CAACD,GAAG,CAACgN,eAAe,EAAEnQ,MAAM,CAACuQ,WAAW,GAAGZ,MAAM,GAAGQ,eAAe,CAAC;UAErF,OAAO;YACHF,IAAI,EAAE7M,IAAI,CAAC2M,KAAK,CAAC9M,KAAK,CAACgN,IAAI,EAAEE,eAAe,EAAEC,OAAO,CAAC,CAAC;YACvDF,GAAG,EAAE9M,IAAI,CAAC2M,KAAK,CAAC9M,KAAK,CAACiN,GAAG,EAAEC,eAAe,EAAEG,MAAM,CAAC;UACvD,CAAC;QACL,CAAC;QACDE,qBAAqB,WAArBA,qBAAqBA,CAACjB,OAAO,EAAEU,IAAI,EAAEC,GAAG,EAAE;UACtC,IAAI,CAACX,OAAO,EAAE;YACV;UACJ;UAEAA,OAAO,CAACkB,KAAK,CAACR,IAAI,GAAGA,IAAI,GAAG,IAAI;UAChCV,OAAO,CAACkB,KAAK,CAACP,GAAG,GAAGA,GAAG,GAAG,IAAI;UAC9BX,OAAO,CAACkB,KAAK,CAACC,KAAK,GAAG,MAAM;UAC5BnB,OAAO,CAACkB,KAAK,CAACE,MAAM,GAAG,MAAM;QACjC,CAAC;QACDC,oBAAoB,WAApBA,oBAAoBA,CAAA,EAAG;UACnB,OAAO;YACHlB,KAAK,EAAE,IAAI,CAAC7D,kBAAkB,IAAIjJ,eAAe,CAAC0E,MAAM,CAACxG,MAAM,CAACa,YAAY,CAAC,IAAI,GAAG;YACpFgO,MAAM,EAAE,IAAI,CAAC7D,mBAAmB,IAAIlJ,eAAe,CAAC0E,MAAM,CAACxG,MAAM,CAACc,aAAa,CAAC,IAAI;UACxF,CAAC;QACL,CAAC;QACDiP,0BAA0B,WAA1BA,0BAA0BA,CAAA,EAAG;UACzB,IAAI,CAAC,IAAI,CAACrF,sBAAsB,IAAI,CAAClE,MAAM,CAACxG,MAAM,CAACY,aAAa,EAAE;YAC9D;UACJ;UAEA,IAAIoP,SAAS,GAAG,IAAI,CAACtF,sBAAsB,CAACqE,qBAAqB,CAAC,CAAC;UACnE,IAAI,CAACf,sBAAsB,CAAC;YACxBI,KAAK,EAAE;cACHe,IAAI,EAAE7M,IAAI,CAAC2M,KAAK,CAACe,SAAS,CAACb,IAAI,CAAC;cAChCC,GAAG,EAAE9M,IAAI,CAAC2M,KAAK,CAACe,SAAS,CAACZ,GAAG;YACjC;UACJ,CAAC,CAAC;QACN,CAAC;QACDa,2BAA2B,WAA3BA,2BAA2BA,CAAA,EAAG;UAC1B,IAAI,CAAC,IAAI,CAACtF,yBAAyB,IAAI,CAACnE,MAAM,CAACxG,MAAM,CAACY,aAAa,EAAE;YACjE;UACJ;UAEA,IAAIsP,UAAU,GAAG,IAAI,CAACvF,yBAAyB,CAACoE,qBAAqB,CAAC,CAAC;UACvE,IAAI,CAACf,sBAAsB,CAAC;YACxBK,MAAM,EAAE;cACJc,IAAI,EAAE7M,IAAI,CAAC2M,KAAK,CAACiB,UAAU,CAACf,IAAI,CAAC;cACjCC,GAAG,EAAE9M,IAAI,CAAC2M,KAAK,CAACiB,UAAU,CAACd,GAAG;YAClC;UACJ,CAAC,CAAC;QACN,CAAC;QACDe,sBAAsB,WAAtBA,sBAAsBA,CAAA,EAAG;UACrB,IAAI,CAAC,IAAI,CAACzF,sBAAsB,IAAI,CAAClE,MAAM,CAACxG,MAAM,CAACW,cAAc,IAAI,CAAC6F,MAAM,CAACxG,MAAM,CAACY,aAAa,EAAE;YAC/F;UACJ;UAEA,IAAIwP,WAAW,GAAG,IAAI,CAACN,oBAAoB,CAAC,CAAC;UAC7C,IAAIO,WAAW,GAAG,IAAI,CAAC7B,cAAc,CAAC,IAAI,CAAC9D,sBAAsB,EAAE0F,WAAW,CAACxB,KAAK,EAAEwB,WAAW,CAACvB,MAAM,CAAC;UAEzG,IAAI,CAACb,sBAAsB,CAAC;YACxBI,KAAK,EAAE;cACHQ,KAAK,EAAEtM,IAAI,CAACgO,GAAG,CAACD,WAAW,CAACzB,KAAK,GAAGwB,WAAW,CAACxB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAGyB,WAAW,CAACzB,KAAK;cACtFC,MAAM,EAAEvM,IAAI,CAACgO,GAAG,CAACD,WAAW,CAACxB,MAAM,GAAGuB,WAAW,CAACvB,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,GAAGwB,WAAW,CAACxB;YACxF;UACJ,CAAC,CAAC;QACN,CAAC;QACD0B,qCAAqC,WAArCA,qCAAqCA,CAAA,EAAG;UACpC,IAAI,CAAC,IAAI,CAAC3F,4BAA4B,EAAE;YACpC;UACJ;UAEA,IAAI,CAACpE,MAAM,CAACxG,MAAM,CAACW,cAAc,IAAI,CAAC,IAAI,CAAC+J,sBAAsB,EAAE;YAC/D,IAAI,CAACE,4BAA4B,CAAC4F,SAAS,CAACC,GAAG,CAAC,QAAQ,CAAC;YACzD;UACJ;UAEA,IAAIL,WAAW,GAAG,IAAI,CAACN,oBAAoB,CAAC,CAAC;UAC7C,IAAIO,WAAW,GAAG,IAAI,CAAC7B,cAAc,CAAC,IAAI,CAAC9D,sBAAsB,EAAE0F,WAAW,CAACxB,KAAK,EAAEwB,WAAW,CAACvB,MAAM,CAAC;UACzG,IAAI6B,SAAS,GACTpO,IAAI,CAACgO,GAAG,CAACD,WAAW,CAACzB,KAAK,GAAGwB,WAAW,CAACxB,KAAK,CAAC,GAAG,CAAC,IACnDtM,IAAI,CAACgO,GAAG,CAACD,WAAW,CAACxB,MAAM,GAAGuB,WAAW,CAACvB,MAAM,CAAC,GAAG,CAAC,IACrD,CAAC,CAAC,IAAI,CAACnE,sBAAsB,CAACiF,KAAK,CAACf,KAAK,IACzC,CAAC,CAAC,IAAI,CAAClE,sBAAsB,CAACiF,KAAK,CAACd,MAAM;UAE9C,IAAI,CAACjE,4BAA4B,CAAC4F,SAAS,CAACnC,MAAM,CAAC,QAAQ,EAAE,CAACqC,SAAS,CAAC;QAC5E,CAAC;QACDC,eAAe,WAAfA,eAAeA,CAAA,EAAG;UACd,IAAI,CAAC,IAAI,CAACjG,sBAAsB,IAAI,CAAClE,MAAM,CAACxG,MAAM,CAACW,cAAc,EAAE;YAC/D;UACJ;UAEA,IAAI,CAAC+J,sBAAsB,CAACiF,KAAK,CAACiB,cAAc,CAAC,OAAO,CAAC;UACzD,IAAI,CAAClG,sBAAsB,CAACiF,KAAK,CAACiB,cAAc,CAAC,QAAQ,CAAC;UAC1D,IAAI,CAACT,sBAAsB,CAAC,CAAC;UAC7B,IAAI,CAACU,iCAAiC,CAAC,CAAC;UACxC,IAAI,CAACN,qCAAqC,CAAC,CAAC;QAChD,CAAC;QACDO,mBAAmB,WAAnBA,mBAAmBA,CAAA,EAAG;UAClB,IAAIjD,YAAY,GAAG,IAAI,CAACD,qBAAqB,CAAC,CAAC;UAE/C,IAAI,IAAI,CAAClD,sBAAsB,IAAIlE,MAAM,CAACxG,MAAM,CAACW,cAAc,EAAE;YAC7D,IAAIoB,MAAM,CAACC,QAAQ,CAAC6L,YAAY,CAACO,KAAK,IAAIP,YAAY,CAACO,KAAK,CAACQ,KAAK,CAAC,EAAE;cACjE,IAAI,CAAClE,sBAAsB,CAACiF,KAAK,CAACf,KAAK,GAAGf,YAAY,CAACO,KAAK,CAACQ,KAAK,GAAG,IAAI;YAC7E,CAAC,MAAM;cACH,IAAI,CAAClE,sBAAsB,CAACiF,KAAK,CAACiB,cAAc,CAAC,OAAO,CAAC;YAC7D;YAEA,IAAI7O,MAAM,CAACC,QAAQ,CAAC6L,YAAY,CAACO,KAAK,IAAIP,YAAY,CAACO,KAAK,CAACS,MAAM,CAAC,EAAE;cAClE,IAAI,CAACnE,sBAAsB,CAACiF,KAAK,CAACd,MAAM,GAAGhB,YAAY,CAACO,KAAK,CAACS,MAAM,GAAG,IAAI;YAC/E,CAAC,MAAM;cACH,IAAI,CAACnE,sBAAsB,CAACiF,KAAK,CAACiB,cAAc,CAAC,QAAQ,CAAC;YAC9D;UACJ;UAEA,IAAI,IAAI,CAAClG,sBAAsB,IAAIlE,MAAM,CAACxG,MAAM,CAACU,cAAc,IAC3DqB,MAAM,CAACC,QAAQ,CAAC6L,YAAY,CAACO,KAAK,IAAIP,YAAY,CAACO,KAAK,CAACe,IAAI,CAAC,IAC9DpN,MAAM,CAACC,QAAQ,CAAC6L,YAAY,CAACO,KAAK,IAAIP,YAAY,CAACO,KAAK,CAACgB,GAAG,CAAC,EAAE;YAC/D,IAAI,CAACM,qBAAqB,CAAC,IAAI,CAAChF,sBAAsB,EAAEmD,YAAY,CAACO,KAAK,CAACe,IAAI,EAAEtB,YAAY,CAACO,KAAK,CAACgB,GAAG,CAAC;UAC5G;UAEA,IAAI,IAAI,CAACzE,yBAAyB,IAAInE,MAAM,CAACxG,MAAM,CAACU,cAAc,IAC9DqB,MAAM,CAACC,QAAQ,CAAC6L,YAAY,CAACQ,MAAM,IAAIR,YAAY,CAACQ,MAAM,CAACc,IAAI,CAAC,IAChEpN,MAAM,CAACC,QAAQ,CAAC6L,YAAY,CAACQ,MAAM,IAAIR,YAAY,CAACQ,MAAM,CAACe,GAAG,CAAC,EAAE;YACjE,IAAI,CAACM,qBAAqB,CAAC,IAAI,CAAC/E,yBAAyB,EAAEkD,YAAY,CAACQ,MAAM,CAACc,IAAI,EAAEtB,YAAY,CAACQ,MAAM,CAACe,GAAG,CAAC;UACjH;UAEA,IAAI,CAACyB,iCAAiC,CAAC,CAAC;UACxC,IAAI,CAACN,qCAAqC,CAAC,CAAC;QAChD,CAAC;QACDQ,4BAA4B,WAA5BA,4BAA4BA,CAACtC,OAAO,EAAEuC,MAAM,EAAEC,SAAS,EAAEC,mBAAmB,EAAE;UAAA,IAAAC,KAAA;UAC1E,IAAI,CAAC1C,OAAO,IAAI,CAACuC,MAAM,IAAI,CAACxK,MAAM,CAACxG,MAAM,CAACU,cAAc,EAAE;YACtD;UACJ;UAEA,IAAI0Q,eAAe,GAAG,IAAI;UAC1B,IAAIC,MAAM,GAAG,CAAC;UACd,IAAIC,MAAM,GAAG,CAAC;UACd,IAAIC,SAAS,GAAG,CAAC;UACjB,IAAIC,QAAQ,GAAG,CAAC;UAChB,IAAIC,OAAO,GAAG,KAAK;UACnB,IAAIC,aAAa,GAAG,CAAC;UACrB,IAAIC,mBAAmB,GAAG,mDAAmD;UAE7E,IAAIC,aAAY,GAAG,SAAfA,YAAYA,CAAIC,KAAK,EAAK;YAC1B,IAAIT,eAAe,KAAK,IAAI,EAAE;cAC1B;YACJ;YAEA,IAAIS,KAAK,IAAIA,KAAK,CAACC,SAAS,KAAKjM,SAAS,IAAIgM,KAAK,CAACC,SAAS,KAAKV,eAAe,EAAE;cAC/E;YACJ;YAEA1P,QAAQ,CAACqQ,mBAAmB,CAAC,aAAa,EAAEC,aAAa,CAAC;YAC1DtQ,QAAQ,CAACqQ,mBAAmB,CAAC,WAAW,EAAEH,aAAY,CAAC;YACvDlQ,QAAQ,CAACqQ,mBAAmB,CAAC,eAAe,EAAEH,aAAY,CAAC;YAC3DnD,OAAO,CAAC+B,SAAS,CAACyB,MAAM,CAAC,yBAAyB,CAAC;YACnDb,eAAe,GAAG,IAAI;YAEtB,IAAI,CAACK,OAAO,EAAE;cACV;YACJ;YAEA,IAAIR,SAAS,KAAK,OAAO,EAAE;cACvBE,KAAI,CAACpB,0BAA0B,CAAC,CAAC;YACrC,CAAC,MAAM,IAAIkB,SAAS,KAAK,QAAQ,EAAE;cAC/BE,KAAI,CAAClB,2BAA2B,CAAC,CAAC;YACtC;YAEA,IAAIiB,mBAAmB,EAAE;cACrBzC,OAAO,CAACyD,OAAO,CAACC,iBAAiB,GAAG,MAAM;cAC1CjT,MAAM,CAACkT,UAAU,CAAC,YAAM;gBACpB,IAAI3D,OAAO,CAACyD,OAAO,CAACC,iBAAiB,KAAK,MAAM,EAAE;kBAC9C1D,OAAO,CAACyD,OAAO,CAACC,iBAAiB,GAAG,OAAO;gBAC/C;cACJ,CAAC,EAAE,CAAC,CAAC;YACT;UACJ,CAAC;UAED,IAAIH,aAAa,GAAG,SAAhBA,aAAaA,CAAIH,KAAK,EAAK;YAC3B,IAAIT,eAAe,KAAK,IAAI,IAAIS,KAAK,CAACC,SAAS,KAAKV,eAAe,EAAE;cACjE;YACJ;YAEA,IAAIiB,MAAM,GAAGR,KAAK,CAACS,OAAO,GAAGjB,MAAM;YACnC,IAAIkB,MAAM,GAAGV,KAAK,CAACW,OAAO,GAAGlB,MAAM;YAEnC,IAAI,CAACG,OAAO,IAAInP,IAAI,CAACmQ,KAAK,CAACJ,MAAM,EAAEE,MAAM,CAAC,GAAGb,aAAa,EAAE;cACxD;YACJ;YAEAD,OAAO,GAAG,IAAI;YAEd,IAAIrB,WAAW,GAAGe,KAAI,CAACrB,oBAAoB,CAAC,CAAC;YAC7C,IAAIO,WAAW,GAAGc,KAAI,CAAC3C,cAAc,CACjCC,OAAO,EACPwC,SAAS,KAAK,OAAO,GAAGb,WAAW,CAACxB,KAAK,GAAG,EAAE,EAC9CqC,SAAS,KAAK,OAAO,GAAGb,WAAW,CAACvB,MAAM,GAAG,EAAE,CAAC;YACpD,IAAI6D,YAAY,GAAGvB,KAAI,CAACjC,mBAAmB,CACvCqC,SAAS,GAAGc,MAAM,EAClBb,QAAQ,GAAGe,MAAM,EACjBlC,WAAW,CAACzB,KAAK,EACjByB,WAAW,CAACxB,MAAM,CAAC;YAEvBsC,KAAI,CAACzB,qBAAqB,CAACjB,OAAO,EAAEiE,YAAY,CAACvD,IAAI,EAAEuD,YAAY,CAACtD,GAAG,CAAC;UAC5E,CAAC;UAED4B,MAAM,CAAC2B,gBAAgB,CAAC,aAAa,EAAE,UAACd,KAAK,EAAK;YAC9C,IAAIA,KAAK,CAACe,MAAM,KAAK,CAAC,EAAE;cACpB;YACJ;YAEA,IAAI3B,SAAS,KAAK,OAAO,IAAIY,KAAK,CAACgB,MAAM,CAACC,OAAO,CAACnB,mBAAmB,CAAC,EAAE;cACpE;YACJ;YAEA,IAAI7C,IAAI,GAAGL,OAAO,CAACM,qBAAqB,CAAC,CAAC;YAC1CsC,MAAM,GAAGQ,KAAK,CAACS,OAAO;YACtBhB,MAAM,GAAGO,KAAK,CAACW,OAAO;YACtBjB,SAAS,GAAGzC,IAAI,CAACK,IAAI;YACrBqC,QAAQ,GAAG1C,IAAI,CAACM,GAAG;YACnBqC,OAAO,GAAG,KAAK;YACfL,eAAe,GAAGS,KAAK,CAACC,SAAS;YACjCrD,OAAO,CAAC+B,SAAS,CAACC,GAAG,CAAC,yBAAyB,CAAC;YAEhD,IAAIO,MAAM,CAAC+B,iBAAiB,EAAE;cAC1B/B,MAAM,CAAC+B,iBAAiB,CAAClB,KAAK,CAACC,SAAS,CAAC;YAC7C;YAEApQ,QAAQ,CAACiR,gBAAgB,CAAC,aAAa,EAAEX,aAAa,CAAC;YACvDtQ,QAAQ,CAACiR,gBAAgB,CAAC,WAAW,EAAEf,aAAY,CAAC;YACpDlQ,QAAQ,CAACiR,gBAAgB,CAAC,eAAe,EAAEf,aAAY,CAAC;YACxDC,KAAK,CAACmB,cAAc,CAAC,CAAC;UAC1B,CAAC,CAAC;QACN,CAAC;QACDnC,iCAAiC,WAAjCA,iCAAiCA,CAAA,EAAG;UAChC,IAAI,IAAI,CAACnG,sBAAsB,IAAI,IAAI,CAACA,sBAAsB,CAACiF,KAAK,CAACR,IAAI,EAAE;YACvE,IAAI8D,gBAAgB,GAAG,IAAI,CAACnD,oBAAoB,CAAC,CAAC;YAClD,IAAIoD,SAAS,GAAG,IAAI,CAAC1E,cAAc,CAAC,IAAI,CAAC9D,sBAAsB,EAAEuI,gBAAgB,CAACrE,KAAK,EAAEqE,gBAAgB,CAACpE,MAAM,CAAC;YACjH,IAAImB,SAAS,GAAG,IAAI,CAACtF,sBAAsB,CAACqE,qBAAqB,CAAC,CAAC;YACnE,IAAIoE,YAAY,GAAG,IAAI,CAACjE,mBAAmB,CAACc,SAAS,CAACb,IAAI,EAAEa,SAAS,CAACZ,GAAG,EAAE8D,SAAS,CAACtE,KAAK,EAAEsE,SAAS,CAACrE,MAAM,CAAC;YAE7G,IAAI,CAACa,qBAAqB,CAAC,IAAI,CAAChF,sBAAsB,EAAEyI,YAAY,CAAChE,IAAI,EAAEgE,YAAY,CAAC/D,GAAG,CAAC;YAE5F,IAAI5I,MAAM,CAACxG,MAAM,CAACY,aAAa,EAAE;cAC7B,IAAI,CAACmP,0BAA0B,CAAC,CAAC;YACrC;UACJ;UAEA,IAAI,IAAI,CAACpF,yBAAyB,IAAI,IAAI,CAACA,yBAAyB,CAACgF,KAAK,CAACR,IAAI,EAAE;YAC7E,IAAIiE,UAAU,GAAG,IAAI,CAAC5E,cAAc,CAAC,IAAI,CAAC7D,yBAAyB,EAAE,EAAE,EAAE,EAAE,CAAC;YAC5E,IAAIuF,UAAU,GAAG,IAAI,CAACvF,yBAAyB,CAACoE,qBAAqB,CAAC,CAAC;YACvE,IAAIsE,aAAa,GAAG,IAAI,CAACnE,mBAAmB,CAACgB,UAAU,CAACf,IAAI,EAAEe,UAAU,CAACd,GAAG,EAAEgE,UAAU,CAACxE,KAAK,EAAEwE,UAAU,CAACvE,MAAM,CAAC;YAElH,IAAI,CAACa,qBAAqB,CAAC,IAAI,CAAC/E,yBAAyB,EAAE0I,aAAa,CAAClE,IAAI,EAAEkE,aAAa,CAACjE,GAAG,CAAC;YAEjG,IAAI5I,MAAM,CAACxG,MAAM,CAACY,aAAa,EAAE;cAC7B,IAAI,CAACqP,2BAA2B,CAAC,CAAC;YACtC;UACJ;QACJ,CAAC;QACDqD,cAAc,WAAdA,cAAcA,CAACnZ,CAAC,EAAE;UACd,IAAI,CAACqM,MAAM,CAAC+M,uBAAuB,EAAE;UACrCpZ,CAAC,CAAC6Y,cAAc,CAAC,CAAC;UAClB7Y,CAAC,CAACqZ,eAAe,CAAC,CAAC;UACnB,IAAI,CAAC3H,UAAU,GAAG,IAAI;UACtB,IAAI4H,SAAS,GAAG,IAAI,CAACvJ,YAAY,GAAG,IAAI,CAACA,YAAY,CAAC4I,OAAO,CAAC,wCAAwC,CAAC,GAAG,IAAI;UAC9G,IAAIW,SAAS,EAAEA,SAAS,CAACjD,SAAS,CAACC,GAAG,CAAC,mBAAmB,CAAC;QAC/D,CAAC;QACDiD,eAAe,WAAfA,eAAeA,CAACvZ,CAAC,EAAE;UACf,IAAI,CAACqM,MAAM,CAAC+M,uBAAuB,EAAE;UACrCpZ,CAAC,CAAC6Y,cAAc,CAAC,CAAC;UAClB7Y,CAAC,CAACqZ,eAAe,CAAC,CAAC;UACnB,IAAI,CAAC3H,UAAU,GAAG,KAAK;UACvB,IAAI4H,SAAS,GAAG,IAAI,CAACvJ,YAAY,GAAG,IAAI,CAACA,YAAY,CAAC4I,OAAO,CAAC,wCAAwC,CAAC,GAAG,IAAI;UAC9G,IAAIW,SAAS,EAAEA,SAAS,CAACjD,SAAS,CAACyB,MAAM,CAAC,mBAAmB,CAAC;QAClE,CAAC;QACD0B,UAAU,WAAVA,UAAUA,CAACxZ,CAAC,EAAE;UACV,IAAI,CAACqM,MAAM,CAAC+M,uBAAuB,EAAE;UACrCpZ,CAAC,CAAC6Y,cAAc,CAAC,CAAC;UAClB7Y,CAAC,CAACqZ,eAAe,CAAC,CAAC;UACnB,IAAI,CAAC3H,UAAU,GAAG,KAAK;UACvB,IAAI4H,SAAS,GAAG,IAAI,CAACvJ,YAAY,GAAG,IAAI,CAACA,YAAY,CAAC4I,OAAO,CAAC,wCAAwC,CAAC,GAAG,IAAI;UAC9G,IAAIW,SAAS,EAAEA,SAAS,CAACjD,SAAS,CAACyB,MAAM,CAAC,mBAAmB,CAAC;UAC9D,IAAI9X,CAAC,CAACyZ,YAAY,IAAIzZ,CAAC,CAACyZ,YAAY,CAACC,KAAK,IAAI1Z,CAAC,CAACyZ,YAAY,CAACC,KAAK,CAAClY,MAAM,GAAG,CAAC,EAAE;YAC3E,IAAI,CAACmY,WAAW,CAAC3Z,CAAC,CAACyZ,YAAY,CAACC,KAAK,CAAC;UAC1C;QACJ,CAAC;QACDE,gBAAgB,WAAhBA,gBAAgBA,CAAA,EAAG;UACf,IAAI,CAACvN,MAAM,CAAC+M,uBAAuB,EAAE;UACrC,IAAIS,SAAS,GAAGtS,QAAQ,CAAC+F,cAAc,CAAC,mBAAmB,CAAC;UAC5D,IAAIuM,SAAS,EAAEA,SAAS,CAACC,KAAK,CAAC,CAAC;QACpC,CAAC;QACDC,qBAAqB,WAArBA,qBAAqBA,CAAC/Z,CAAC,EAAE;UACrB,IAAI0Z,KAAK,GAAG1Z,CAAC,CAAC0Y,MAAM,CAACgB,KAAK;UAC1B,IAAIA,KAAK,IAAIA,KAAK,CAAClY,MAAM,GAAG,CAAC,EAAE;YAC3B,IAAI,CAACmY,WAAW,CAACD,KAAK,CAAC;UAC3B;UACA1Z,CAAC,CAAC0Y,MAAM,CAAC7W,KAAK,GAAG,EAAE;QACvB,CAAC;QACK8X,WAAW,WAAXA,WAAWA,CAACD,KAAK,EAAE;UAAA,IAAAM,MAAA;UAAA,OAAA/W,iBAAA,cAAAb,YAAA,GAAAE,CAAA,UAAA2X,QAAA;YAAA,IAAAC,SAAA,EAAAC,SAAA,EAAAC,QAAA,EAAA5Z,CAAA,EAAA6Z,QAAA,EAAAC,SAAA,EAAAC,WAAA,EAAAC,MAAA,EAAAC,CAAA,EAAAC,EAAA;YAAA,OAAAtY,YAAA,GAAAC,CAAA,WAAAsY,QAAA;cAAA,kBAAAA,QAAA,CAAA1Z,CAAA,GAAA0Z,QAAA,CAAAva,CAAA;gBAAA;kBAAA,IAChBiM,MAAM,CAACuO,iBAAiB;oBAAAD,QAAA,CAAAva,CAAA;oBAAA;kBAAA;kBAAA,OAAAua,QAAA,CAAAtZ,CAAA;gBAAA;kBAEzB6Y,SAAS,GAAGF,MAAI,CAACa,YAAY,CAAC,CAAC;kBAC/BV,SAAS,GAAGH,MAAI,CAACc,YAAY,CAAC,CAAC;kBAAA,MAE/B,CAACZ,SAAS,IAAI,CAACC,SAAS;oBAAAQ,QAAA,CAAAva,CAAA;oBAAA;kBAAA;kBACxBoN,OAAO,CAACC,IAAI,CAAC,uDAAuD,CAAC;kBAAC,OAAAkN,QAAA,CAAAtZ,CAAA;gBAAA;kBAI1E2Y,MAAI,CAACxI,WAAW,GAAG,IAAI;kBACvBwI,MAAI,CAACvI,YAAY,GAAG,EAAE;kBACtBuI,MAAI,CAACe,iBAAiB,CAAC,CAAC;kBAACJ,QAAA,CAAA1Z,CAAA;kBAEjBmZ,QAAQ,GAAG,IAAIY,QAAQ,CAAC,CAAC;kBAC7B,IAAId,SAAS,EAAE;oBACXE,QAAQ,CAACa,MAAM,CAAC,WAAW,EAAEf,SAAS,CAAC;kBAC3C,CAAC,MAAM;oBACHE,QAAQ,CAACa,MAAM,CAAC,WAAW,EAAEd,SAAS,CAAC;kBAC3C;kBACA,KAAS3Z,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGkZ,KAAK,CAAClY,MAAM,EAAEhB,CAAC,EAAE,EAAE;oBACnC4Z,QAAQ,CAACa,MAAM,CAAC,OAAO,EAAEvB,KAAK,CAAClZ,CAAC,CAAC,CAAC;kBACtC;kBAACma,QAAA,CAAAva,CAAA;kBAAA,OAEoB8a,KAAK,CAAC7O,MAAM,CAACuO,iBAAiB,EAAE;oBACjDO,MAAM,EAAE,MAAM;oBACdC,IAAI,EAAEhB;kBACV,CAAC,CAAC;gBAAA;kBAHEC,QAAQ,GAAAM,QAAA,CAAAvZ,CAAA;kBAAA,IAKPiZ,QAAQ,CAACgB,EAAE;oBAAAV,QAAA,CAAAva,CAAA;oBAAA;kBAAA;kBAAAua,QAAA,CAAAva,CAAA;kBAAA,OACUia,QAAQ,CAAChT,IAAI,CAAC,CAAC;gBAAA;kBAAjCiT,SAAS,GAAAK,QAAA,CAAAvZ,CAAA;kBACTmZ,WAAW,GAAGP,MAAI,CAACsB,2BAA2B,CAAChB,SAAS,EAAE,kCAAkC,CAAC;kBACjG9M,OAAO,CAACe,KAAK,CAAC,gBAAgB,EAAE+L,SAAS,CAAC;kBAC1CN,MAAI,CAACvI,YAAY,GAAG,CAAC;oBAAE8J,QAAQ,EAAE,EAAE;oBAAEhN,KAAK,EAAEgM;kBAAY,CAAC,CAAC;kBAAC,OAAAI,QAAA,CAAAtZ,CAAA;gBAAA;kBAAAsZ,QAAA,CAAAva,CAAA;kBAAA,OAI5Cia,QAAQ,CAAClO,IAAI,CAAC,CAAC;gBAAA;kBAA9BqO,MAAM,GAAAG,QAAA,CAAAvZ,CAAA;kBAEV;kBACA,IAAIoZ,MAAM,CAACN,SAAS,IAAI,CAACA,SAAS,EAAE;oBAChCF,MAAI,CAACwB,iBAAiB,CAAChB,MAAM,CAACN,SAAS,CAAC;kBAC5C;kBAEA,IAAIM,MAAM,CAACiB,QAAQ,IAAIjB,MAAM,CAACiB,QAAQ,CAACja,MAAM,GAAG,CAAC,EAAE;oBAC/C,KAASiZ,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGD,MAAM,CAACiB,QAAQ,CAACja,MAAM,EAAEiZ,CAAC,EAAE,EAAE;sBAC7CT,MAAI,CAAC1I,SAAS,CAACzM,IAAI,CAAC2V,MAAM,CAACiB,QAAQ,CAAChB,CAAC,CAAC,CAAC;oBAC3C;kBACJ;kBACA,IAAID,MAAM,CAACkB,MAAM,IAAIlB,MAAM,CAACkB,MAAM,CAACla,MAAM,GAAG,CAAC,EAAE;oBAC3CwY,MAAI,CAACvI,YAAY,GAAG+I,MAAM,CAACkB,MAAM;kBACrC;kBAACf,QAAA,CAAAva,CAAA;kBAAA;gBAAA;kBAAAua,QAAA,CAAA1Z,CAAA;kBAAAyZ,EAAA,GAAAC,QAAA,CAAAvZ,CAAA;kBAEDoM,OAAO,CAACe,KAAK,CAAC,eAAe,EAAAmM,EAAK,CAAC;kBACnCV,MAAI,CAACvI,YAAY,GAAG,CAAC;oBAAE8J,QAAQ,EAAE,EAAE;oBAAEhN,KAAK,EAAE;kBAAmC,CAAC,CAAC;gBAAC;kBAAAoM,QAAA,CAAA1Z,CAAA;kBAElF+Y,MAAI,CAACxI,WAAW,GAAG,KAAK;kBACxBwI,MAAI,CAACe,iBAAiB,CAAC,CAAC;kBAAC,OAAAJ,QAAA,CAAA3Z,CAAA;gBAAA;kBAAA,OAAA2Z,QAAA,CAAAtZ,CAAA;cAAA;YAAA,GAAA4Y,OAAA;UAAA;QAEjC,CAAC;QACK0B,cAAc,WAAdA,cAAcA,CAACC,GAAG,EAAE;UAAA,IAAAC,MAAA;UAAA,OAAA5Y,iBAAA,cAAAb,YAAA,GAAAE,CAAA,UAAAwZ,SAAA;YAAA,IAAA5B,SAAA,EAAAG,QAAA,EAAA7O,GAAA,EAAA8O,SAAA,EAAAyB,WAAA,EAAAC,GAAA;YAAA,OAAA5Z,YAAA,GAAAC,CAAA,WAAA4Z,SAAA;cAAA,kBAAAA,SAAA,CAAAhb,CAAA,GAAAgb,SAAA,CAAA7b,CAAA;gBAAA;kBAAA,IACjBiM,MAAM,CAAC6P,iBAAiB;oBAAAD,SAAA,CAAA7b,CAAA;oBAAA;kBAAA;kBAAA,OAAA6b,SAAA,CAAA5a,CAAA;gBAAA;kBAAA4a,SAAA,CAAAhb,CAAA;kBAGrBiZ,SAAS,GAAG2B,MAAI,CAAChB,YAAY,CAAC,CAAC;kBAAAoB,SAAA,CAAA7b,CAAA;kBAAA,OACd8a,KAAK,CAAC7O,MAAM,CAAC6P,iBAAiB,EAAE;oBACjDf,MAAM,EAAE,MAAM;oBACdgB,OAAO,EAAE;sBAAE,cAAc,EAAE;oBAAmB,CAAC;oBAC/Cf,IAAI,EAAEnN,IAAI,CAACmG,SAAS,CAAC;sBAAEgI,MAAM,EAAElC,SAAS;sBAAEmC,UAAU,EAAET,GAAG,CAACS;oBAAW,CAAC;kBAC1E,CAAC,CAAC;gBAAA;kBAJEhC,QAAQ,GAAA4B,SAAA,CAAA7a,CAAA;kBAAA,KAMRiZ,QAAQ,CAACgB,EAAE;oBAAAY,SAAA,CAAA7b,CAAA;oBAAA;kBAAA;kBACPoL,GAAG,GAAGqQ,MAAI,CAACvK,SAAS,CAAC7F,OAAO,CAACmQ,GAAG,CAAC;kBACrC,IAAIpQ,GAAG,GAAG,CAAC,CAAC,EAAEqQ,MAAI,CAACvK,SAAS,CAACgL,MAAM,CAAC9Q,GAAG,EAAE,CAAC,CAAC;kBAACyQ,SAAA,CAAA7b,CAAA;kBAAA;gBAAA;kBAAA6b,SAAA,CAAA7b,CAAA;kBAAA,OAEtBia,QAAQ,CAAChT,IAAI,CAAC,CAAC;gBAAA;kBAAjCiT,SAAS,GAAA2B,SAAA,CAAA7a,CAAA;kBACT2a,WAAW,GAAGF,MAAI,CAACP,2BAA2B,CAAChB,SAAS,EAAE,8CAA8C,CAAC;kBAC7G9M,OAAO,CAACe,KAAK,CAAC,4BAA4B,EAAE8L,QAAQ,CAACkC,MAAM,EAAEjC,SAAS,CAAC;kBACvEuB,MAAI,CAACpK,YAAY,GAAG,CAAC;oBAAE8J,QAAQ,EAAEK,GAAG,CAACL,QAAQ,IAAI,EAAE;oBAAEhN,KAAK,EAAEwN;kBAAY,CAAC,CAAC;kBAC1EF,MAAI,CAACd,iBAAiB,CAAC,CAAC;gBAAC;kBAAAkB,SAAA,CAAA7b,CAAA;kBAAA;gBAAA;kBAAA6b,SAAA,CAAAhb,CAAA;kBAAA+a,GAAA,GAAAC,SAAA,CAAA7a,CAAA;kBAG7BoM,OAAO,CAACe,KAAK,CAAC,wBAAwB,EAAAyN,GAAK,CAAC;kBAC5CH,MAAI,CAACpK,YAAY,GAAG,CAAC;oBAAE8J,QAAQ,EAAEK,GAAG,CAACL,QAAQ,IAAI,EAAE;oBAAEhN,KAAK,EAAE;kBAA+C,CAAC,CAAC;kBAC7GsN,MAAI,CAACd,iBAAiB,CAAC,CAAC;gBAAC;kBAAA,OAAAkB,SAAA,CAAA5a,CAAA;cAAA;YAAA,GAAAya,QAAA;UAAA;QAEjC,CAAC;QACDU,cAAc,WAAdA,cAAcA,CAACC,KAAK,EAAE;UAClB,IAAIA,KAAK,GAAG,IAAI,EAAE,OAAOA,KAAK,GAAG,IAAI;UACrC,IAAIA,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE,OAAO,CAACA,KAAK,GAAG,IAAI,EAAEC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK;UACjE,OAAO,CAACD,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,EAAEC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK;QACrD,CAAC;QACD3B,iBAAiB,WAAjBA,iBAAiBA,CAAA,EAAG;UAChB,IAAI,CAAC,IAAI,CAACpJ,WAAW,EAAE;UAEvB,IAAI,CAACtF,MAAM,CAAC+M,uBAAuB,EAAE;YACjC,IAAI,CAACzH,WAAW,CAAC0E,SAAS,CAACC,GAAG,CAAC,QAAQ,CAAC;YACxC;UACJ;UAEA,IAAI,CAAC3E,WAAW,CAAC0E,SAAS,CAACyB,MAAM,CAAC,QAAQ,CAAC;UAE3C,IAAI/I,IAAI,GAAG,mCAAmC;UAC9CA,IAAI,IAAI,yDAAyD;UAEjE,KAAK,IAAIvO,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG,IAAI,CAAC8Q,SAAS,CAAC9P,MAAM,EAAEhB,CAAC,EAAE,EAAE;YAC5C,IAAIob,GAAG,GAAG,IAAI,CAACtK,SAAS,CAAC9Q,CAAC,CAAC;YAC3B,IAAImE,IAAI,GAAGiX,GAAG,CAACL,QAAQ,IAAI,UAAU;YACrC,IAAI5W,IAAI,CAACnD,MAAM,GAAG,EAAE,EAAEmD,IAAI,GAAGA,IAAI,CAACsH,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;YAC1D8C,IAAI,IAAI,8IAA8I,GAAG,IAAI,CAAC4N,UAAU,CAACf,GAAG,CAACL,QAAQ,IAAI,EAAE,CAAC,GAAG,IAAI;YACnMxM,IAAI,IAAI,oEAAoE;YAC5EA,IAAI,IAAI,IAAI,CAAC4N,UAAU,CAAChY,IAAI,CAAC;YAC7BoK,IAAI,IAAI,wGAAwG,GAAGvO,CAAC,GAAG,iCAAiC;YACxJuO,IAAI,IAAI,SAAS;UACrB;UAEA,KAAK,IAAIzM,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG,IAAI,CAACmP,YAAY,CAACjQ,MAAM,EAAEc,CAAC,EAAE,EAAE;YAC/C,IAAIsa,UAAU,GAAG,IAAI,CAACnL,YAAY,CAACnP,CAAC,CAAC;YACrC,IAAIua,UAAU,GAAGD,UAAU,CAACrB,QAAQ,IAAI,MAAM;YAC9C,IAAIuB,QAAQ,GAAGF,UAAU,CAACrO,KAAK,IAAI,eAAe;YAClD,IAAIsO,UAAU,CAACrb,MAAM,GAAG,EAAE,EAAEqb,UAAU,GAAGA,UAAU,CAAC5Q,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;YAC5E8C,IAAI,IAAI,6IAA6I,GAAG,IAAI,CAAC4N,UAAU,CAAC,CAACC,UAAU,CAACrB,QAAQ,IAAI,EAAE,IAAI,IAAI,GAAGuB,QAAQ,CAAC,GAAG,IAAI;YAC7N/N,IAAI,IAAI,4EAA4E;YACpFA,IAAI,IAAI,IAAI,CAAC4N,UAAU,CAACE,UAAU,CAAC;YACnC9N,IAAI,IAAI,0GAA0G,GAAGzM,CAAC,GAAG,kCAAkC;YAC3JyM,IAAI,IAAI,SAAS;UACrB;UAEA,IAAI,IAAI,CAACyC,WAAW,EAAE;YAClBzC,IAAI,IAAI,kIAAkI;YAC1IA,IAAI,IAAI,4GAA4G;YACpHA,IAAI,IAAI,SAAS;UACrB;UAEAA,IAAI,IAAI,uNAAuN;UAC/NA,IAAI,IAAI,uCAAuC;UAC/C,IAAI,IAAI,CAACuC,SAAS,CAAC9P,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAACgQ,WAAW,EAAE;YAClDzC,IAAI,IAAI,4BAA4B;UACxC;UACAA,IAAI,IAAI,WAAW;UACnBA,IAAI,IAAI,QAAQ;UAChB,IAAI1C,MAAM,CAAC0Q,uBAAuB,EAAE;YAChChO,IAAI,IAAI,wDAAwD,GAAG,IAAI,CAAC4N,UAAU,CAACtQ,MAAM,CAAC0Q,uBAAuB,CAAC,GAAG,QAAQ;UACjI;UAEAhO,IAAI,IAAI,QAAQ;UAEhB,IAAI,CAAC4C,WAAW,CAACqL,eAAe,CAAChO,SAAS,CAACC,QAAQ,CAACF,IAAI,EAAE;YAAEkO,mBAAmB,EAAE;UAAK,CAAC,CAAC,CAAC;;UAEzF;UACA,IAAIC,IAAI,GAAG,IAAI;UACf,IAAIC,YAAY,GAAG,IAAI,CAACxL,WAAW,CAACyL,gBAAgB,CAAC,kBAAkB,CAAC;UACxE,KAAK,IAAI3C,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG0C,YAAY,CAAC3b,MAAM,EAAEiZ,CAAC,EAAE,EAAE;YAC1C0C,YAAY,CAAC1C,CAAC,CAAC,CAACjC,gBAAgB,CAAC,OAAO,EAAG,UAAUhN,GAAG,EAAE;cACtD,OAAO,UAAUxL,CAAC,EAAE;gBAChBA,CAAC,CAAC6Y,cAAc,CAAC,CAAC;gBAClB7Y,CAAC,CAACqZ,eAAe,CAAC,CAAC;gBACnB,IAAIgE,WAAW,GAAGH,IAAI,CAAC5L,SAAS,CAAC9F,GAAG,CAAC;gBACrC,IAAI6R,WAAW,EAAEH,IAAI,CAACvB,cAAc,CAAC0B,WAAW,CAAC;cACrD,CAAC;YACL,CAAC,CAAEC,QAAQ,CAACH,YAAY,CAAC1C,CAAC,CAAC,CAAC8C,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;UACjE;;UAEA;UACA,IAAIC,iBAAiB,GAAG,IAAI,CAAC7L,WAAW,CAACyL,gBAAgB,CAAC,oBAAoB,CAAC;UAC/E,KAAK,IAAIhd,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGod,iBAAiB,CAAChc,MAAM,EAAEpB,CAAC,EAAE,EAAE;YAC/Cod,iBAAiB,CAACpd,CAAC,CAAC,CAACoY,gBAAgB,CAAC,OAAO,EAAG,UAAUhN,GAAG,EAAE;cAC3D,OAAO,UAAUxL,CAAC,EAAE;gBAChBA,CAAC,CAAC6Y,cAAc,CAAC,CAAC;gBAClB7Y,CAAC,CAACqZ,eAAe,CAAC,CAAC;gBACnB6D,IAAI,CAACzL,YAAY,CAAC6K,MAAM,CAAC9Q,GAAG,EAAE,CAAC,CAAC;gBAChC0R,IAAI,CAACnC,iBAAiB,CAAC,CAAC;cAC5B,CAAC;YACL,CAAC,CAAEuC,QAAQ,CAACE,iBAAiB,CAACpd,CAAC,CAAC,CAACmd,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;UACxE;;UAEA;UACA,IAAIE,MAAM,GAAG,IAAI,CAAC9L,WAAW,CAAC+L,aAAa,CAAC,sBAAsB,CAAC;UACnE,IAAID,MAAM,EAAE;YACRA,MAAM,CAACjF,gBAAgB,CAAC,OAAO,EAAE,UAAUxY,CAAC,EAAE;cAC1CA,CAAC,CAAC6Y,cAAc,CAAC,CAAC;cAClBqE,IAAI,CAACtD,gBAAgB,CAAC,CAAC;YAC3B,CAAC,CAAC;UACN;QACJ,CAAC;QACD+C,UAAU,WAAVA,UAAUA,CAACtV,IAAI,EAAE;UACb,IAAIsW,GAAG,GAAGpW,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;UACvCmW,GAAG,CAAClW,WAAW,GAAGJ,IAAI;UACtB,OAAOsW,GAAG,CAACjW,SAAS;QACxB,CAAC;QACD4T,2BAA2B,WAA3BA,2BAA2BA,CAAChB,SAAS,EAAEsD,eAAe,EAAE;UACpD,IAAI,CAACtD,SAAS,IAAI,OAAOA,SAAS,KAAK,QAAQ,EAAE;YAC7C,OAAOsD,eAAe;UAC1B;UAEA,IAAI1W,OAAO,GAAGoT,SAAS,CAACnT,IAAI,CAAC,CAAC;UAC9B,IAAI,CAACD,OAAO,EAAE;YACV,OAAO0W,eAAe;UAC1B;UAEA,IAAI1W,OAAO,CAAC2W,UAAU,CAAC,GAAG,CAAC,IAAI3W,OAAO,CAAC2W,UAAU,CAAC,GAAG,CAAC,EAAE;YACpD,IAAI;cACA,IAAI/V,MAAM,GAAGmG,IAAI,CAACC,KAAK,CAAChH,OAAO,CAAC;cAChC,IAAI4F,OAAO,GAAG,CAAAhF,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEyG,KAAK,MAAIzG,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEgF,OAAO,MAAIhF,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEgW,KAAK,MAAIhW,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEiW,MAAM;cACjF,OAAO,OAAOjR,OAAO,KAAK,QAAQ,IAAIA,OAAO,CAAC3F,IAAI,CAAC,CAAC,GAC9C2F,OAAO,CAAC3F,IAAI,CAAC,CAAC,GACdyW,eAAe;YACzB,CAAC,CAAC,OAAOxQ,GAAG,EAAE;cACV,OAAOwQ,eAAe;YAC1B;UACJ;UAEA,IAAI,SAAS,CAAChZ,IAAI,CAACsC,OAAO,CAAC,EAAE;YACzB,OAAO0W,eAAe;UAC1B;UAEA,OAAO1W,OAAO;QAClB,CAAC;QACD8W,4BAA4B,WAA5BA,4BAA4BA,CAACC,UAAU,EAAE;UACrC,IAAI,CAACA,UAAU,EAAE;YACb,OAAO,IAAI;UACf;UAEA,IAAIC,KAAK,GAAG,OAAOD,UAAU,CAACC,KAAK,KAAK,QAAQ,GAAGD,UAAU,CAACC,KAAK,CAAC/W,IAAI,CAAC,CAAC,GAAG,EAAE;UAC/E,IAAIgX,IAAI,GAAG,OAAOF,UAAU,CAACE,IAAI,KAAK,QAAQ,GAAGF,UAAU,CAACE,IAAI,CAAChX,IAAI,CAAC,CAAC,GAAG,EAAE;UAC5E,IAAIiX,QAAQ,GAAG,OAAOH,UAAU,CAACG,QAAQ,KAAK,QAAQ,GAAGH,UAAU,CAACG,QAAQ,CAACjX,IAAI,CAAC,CAAC,GAAG,EAAE;UACxF,IAAIkX,yBAAyB,GAAG,CAAC,CAACJ,UAAU,CAACI,yBAAyB;UAEtE,IAAI,CAACH,KAAK,IAAI,CAACC,IAAI,IAAI,CAACC,QAAQ,IAAI,CAACC,yBAAyB,EAAE;YAC5D,OAAO,IAAI;UACf;UAEA,OAAO;YACHH,KAAK,EAAEA,KAAK;YACZC,IAAI,EAAEA,IAAI;YACVC,QAAQ,EAAEA,QAAQ;YAClBC,yBAAyB,EAAEA;UAC/B,CAAC;QACL,CAAC;QACDC,iBAAiB,WAAjBA,iBAAiBA,CAACxR,OAAO,EAAE;UACvB,IAAImR,UAAU,GAAGnR,OAAO,GAAG,IAAI,CAACkR,4BAA4B,CAAClR,OAAO,CAACmR,UAAU,CAAC,GAAG,IAAI;UACvF,OAAOA,UAAU,IAAIA,UAAU,CAACC,KAAK,GAAGD,UAAU,CAACC,KAAK,GAAG,IAAI,CAAC1Y,cAAc;QAClF,CAAC;QACD+Y,uBAAuB,WAAvBA,uBAAuBA,CAACzR,OAAO,EAAE;UAC7B,IAAImR,UAAU,GAAGnR,OAAO,GAAG,IAAI,CAACkR,4BAA4B,CAAClR,OAAO,CAACmR,UAAU,CAAC,GAAG,IAAI;UACvF,IAAIO,OAAO,GAAG,CAAC,kBAAkB,CAAC;UAElC,IAAIP,UAAU,IAAIA,UAAU,CAACG,QAAQ,EAAE;YACnCI,OAAO,CAAC3Z,IAAI,CAACoZ,UAAU,CAACG,QAAQ,CAAC;UACrC,CAAC,MAAM;YACHI,OAAO,CAAC3Z,IAAI,CAAC,4BAA4B,CAAC;UAC9C;UAEA,OAAO2Z,OAAO;QAClB,CAAC;QACDC,uBAAuB,WAAvBA,uBAAuBA,CAAC3R,OAAO,EAAEhE,KAAK,EAAE;UACpC,IAAImV,UAAU,GAAGnR,OAAO,GAAG,IAAI,CAACkR,4BAA4B,CAAClR,OAAO,CAACmR,UAAU,CAAC,GAAG,IAAI;UACvF,OAAO,CAAC,IAAI,CAACS,0BAA0B,CAAC5R,OAAO,EAAEhE,KAAK,CAAC,GAAG,mBAAmB,GAAG,aAAa,EAAEmV,UAAU,IAAIA,UAAU,CAACG,QAAQ,GAAGH,UAAU,CAACG,QAAQ,GAAG,EAAE,CAAC;QAChK,CAAC;QACDO,gBAAgB,WAAhBA,gBAAgBA,CAAC7R,OAAO,EAAE;UACtB,IAAImR,UAAU,GAAGnR,OAAO,GAAG,IAAI,CAACkR,4BAA4B,CAAClR,OAAO,CAACmR,UAAU,CAAC,GAAG,IAAI;UACvF,OAAOA,UAAU,IAAIA,UAAU,CAACE,IAAI,GAAGF,UAAU,CAACE,IAAI,GAAG,aAAa;QAC1E,CAAC;QACDO,0BAA0B,WAA1BA,0BAA0BA,CAAC5R,OAAO,EAAEhE,KAAK,EAAE;UACvC,IAAImV,UAAU,GAAGnR,OAAO,GAAG,IAAI,CAACkR,4BAA4B,CAAClR,OAAO,CAACmR,UAAU,CAAC,GAAG,IAAI;UACvF,OAAO,CAAC,CAACnR,OAAO,IACZA,OAAO,CAACiE,WAAW,IACnBjI,KAAK,KAAK,IAAI,CAACuK,kBAAkB,IACjC,EAAE4K,UAAU,IAAIA,UAAU,CAACI,yBAAyB,CAAC;QAC7D,CAAC;QACKO,eAAe,WAAfA,eAAeA,CAAA,EAAG;UAAA,IAAAC,MAAA;UAAA,OAAA5b,iBAAA,cAAAb,YAAA,GAAAE,CAAA,UAAAwc,SAAA;YAAA,IAAAC,GAAA;YAAA,OAAA3c,YAAA,GAAAC,CAAA,WAAA2c,SAAA;cAAA,kBAAAA,SAAA,CAAA/d,CAAA,GAAA+d,SAAA,CAAA5e,CAAA;gBAAA;kBACpBye,MAAI,CAACI,UAAU,GAAG,IAAIC,OAAO,CAACC,oBAAoB,CAAC,CAAC,CAC/CC,OAAO,CAAC/S,MAAM,CAACkD,aAAa,CAAC,CAC7B8P,sBAAsB,CAAC,CAAC,CACxBC,KAAK,CAAC,CAAC;;kBAEZ;kBACA;kBACAT,MAAI,CAACI,UAAU,CAACM,2BAA2B,GAAG,MAAM;kBACpDV,MAAI,CAACI,UAAU,CAACO,+BAA+B,GAAG,KAAK;kBAEvDX,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,aAAa,EAAE,UAAC3V,IAAI,EAAK;oBAAA,IAAA4V,cAAA;oBACxCb,MAAI,CAACrD,iBAAiB,CAAC1R,IAAI,CAACoQ,SAAS,EAAE,IAAI,CAAC;oBAC5C2E,MAAI,CAAC1N,QAAQ,GAAG,EAAE;oBAClB0N,MAAI,CAACvN,SAAS,GAAGxH,IAAI,CAACwH,SAAS,IAAI,EAAE;oBAErC,EAAAoO,cAAA,GAAC5V,IAAI,CAACqH,QAAQ,cAAAuO,cAAA,cAAAA,cAAA,GAAI,EAAE,EAAEC,OAAO,CAAC,UAAAC,GAAG,EAAI;sBACjCf,MAAI,CAACgB,UAAU,CAACD,GAAG,CAAC;sBAEpBf,MAAI,CAACiB,SAAS,CAAC,YAAM;wBACjBjT,qBAAqB,CAAC+S,GAAG,CAAC;sBAC9B,CAAC,CAAC;oBACN,CAAC,CAAC;;oBAEF;oBACAf,MAAI,CAACiB,SAAS,CAAC,YAAM;sBACjBjB,MAAI,CAACkB,uBAAuB,CAAC,CAAC;oBAClC,CAAC,CAAC;;oBAEF;oBACA;oBACA,IAAIlB,MAAI,CAAC1N,QAAQ,CAAC3P,MAAM,KAAK,CAAC,IAAI6K,MAAM,CAAC2T,aAAa,EAAE;sBACpDnB,MAAI,CAACxN,MAAM,GAAGhF,MAAM,CAAC2T,aAAa;sBAClCnB,MAAI,CAACoB,WAAW,CAAC,CAAC;oBACtB;kBACJ,CAAC,CAAC;kBAEFpB,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,cAAc,EAAE,UAAClR,KAAK,EAAK;oBAC1Cf,OAAO,CAACe,KAAK,CAAC,iBAAiB,EAAEA,KAAK,CAAC;oBAEvC,IAAIsQ,MAAI,CAAChN,WAAW,EAAE;sBAClBgN,MAAI,CAACqB,aAAa,CAAC,CAAC;oBACxB;;oBAEA;oBACA;oBACA,IAAIrB,MAAI,CAAC/N,mBAAmB,IAAI,CAAC+N,MAAI,CAAC1O,gBAAgB,IAAI,CAAC0O,MAAI,CAACsB,yBAAyB,EAAE;sBACvFtB,MAAI,CAACsB,yBAAyB,GAAG,IAAI;sBACrCxM,YAAY,CAACyM,UAAU,CAACvB,MAAI,CAACxO,sBAAsB,CAAC;sBACpDwO,MAAI,CAACwB,eAAe,CAAC,CAAC;oBAC1B;kBACJ,CAAC,CAAC;kBAEFxB,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,cAAc,EAAE,UAACa,SAAS,EAAEC,UAAU,EAAK;oBAC1D,IAAIX,GAAG,GAAGf,MAAI,CAAC1N,QAAQ,CAACqP,IAAI,CAAC,UAAAle,CAAC;sBAAA,OAAIA,CAAC,CAACme,EAAE,KAAKH,SAAS;oBAAA,EAAC;oBACrD,IAAIV,GAAG,EAAE;sBACLA,GAAG,CAACW,UAAU,GAAGA,UAAU;oBAC/B;kBACJ,CAAC,CAAC;kBAEF1B,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,mBAAmB,EAAE,UAACvF,SAAS,EAAE7S,IAAI,EAAEqZ,OAAO,EAAK;oBAClE,IAAI7B,MAAI,CAAC3L,kBAAkB,EAAE;sBACzB,IAAI,CAACwN,OAAO,IAAIrZ,IAAI,EAAE;wBAClBwX,MAAI,CAAC8B,8BAA8B,GAAGtZ,IAAI;wBAC1C,IAAIuZ,OAAO,GAAGvZ,IAAI,CAACwZ,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;wBACrF,IAAI9R,IAAI,GAAG,mCAAmC,GAAG6R,OAAO,GAAG,MAAM;;wBAEjE;wBACA,IAAI,CAAC/B,MAAI,CAACiC,2BAA2B,EAAE;0BACnCjC,MAAI,CAACkC,eAAe,CAAC,CAAC;0BACtBlC,MAAI,CAACiC,2BAA2B,GAAG;4BAC/BxN,IAAI,EAAE,MAAM;4BACZxE,OAAO,EAAEzH,IAAI;4BACb2Z,WAAW,EAAEjS,IAAI;4BACjBkS,SAAS,EAAE;0BACf,CAAC;0BACDpC,MAAI,CAAC1N,QAAQ,CAACtM,IAAI,CAACga,MAAI,CAACiC,2BAA2B,CAAC;wBACxD,CAAC,MAAM;0BACHjC,MAAI,CAACiC,2BAA2B,CAAChS,OAAO,GAAGzH,IAAI;0BAC/CwX,MAAI,CAACiC,2BAA2B,CAACE,WAAW,GAAGjS,IAAI;wBACvD;wBACA8P,MAAI,CAACqC,cAAc,CAAC,CAAC;sBACzB;sBACA;oBACJ;oBAEA,IAAI7Z,IAAI,IAAI,CAACwX,MAAI,CAACsC,eAAe,EAAE;sBAC/BtC,MAAI,CAACxN,MAAM,GAAGwN,MAAI,CAAC9M,kBAAkB,GAAG1K,IAAI;sBAC5C,IAAIwX,MAAI,CAAC9O,YAAY,EAAE;wBACnB8O,MAAI,CAAC9O,YAAY,CAAClO,KAAK,GAAGgd,MAAI,CAACxN,MAAM;wBACrCwN,MAAI,CAAC9O,YAAY,CAACqR,aAAa,CAAC,IAAIC,KAAK,CAAC,OAAO,CAAC,CAAC;sBACvD;oBACJ;kBACJ,CAAC,CAAC;kBAEFxC,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,gCAAgC,EAAE,UAACvF,SAAS,EAAE7S,IAAI,EAAK;oBACtE,IAAIA,IAAI,EAAE;sBACNwX,MAAI,CAACyC,SAAS,CAAC,CAAC;;sBAEhB;sBACA;sBACA,IAAIzC,MAAI,CAAC0C,6BAA6B,EAAE;wBACpC,IAAIC,MAAM,GAAG3C,MAAI,CAAC1N,QAAQ,CAAC0N,MAAI,CAAC0C,6BAA6B,CAACzY,KAAK,CAAC;wBACpE,IAAI0Y,MAAM,EAAE;0BACRA,MAAM,CAACzQ,WAAW,GAAG,KAAK;wBAC9B;wBACA8N,MAAI,CAAC0C,6BAA6B,GAAG,IAAI;sBAC7C;;sBAEA;sBACA,IAAI1C,MAAI,CAACiC,2BAA2B,EAAE;wBAClC,IAAIF,OAAO,GAAGvZ,IAAI,CAACwZ,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;wBACrFhC,MAAI,CAACiC,2BAA2B,CAAChS,OAAO,GAAGzH,IAAI;wBAC/CwX,MAAI,CAACiC,2BAA2B,CAACE,WAAW,GAAG,KAAK,GAAGJ,OAAO,GAAG,MAAM;wBACvE/B,MAAI,CAACiC,2BAA2B,CAACG,SAAS,GAAG,KAAK;wBAClDpC,MAAI,CAACiC,2BAA2B,GAAG,IAAI;sBAC3C,CAAC,MAAM;wBACHjC,MAAI,CAACgB,UAAU,CAAC;0BACZvM,IAAI,EAAE,MAAM;0BACZxE,OAAO,EAAEzH;wBACb,CAAC,CAAC;sBACN;sBACAwX,MAAI,CAACqC,cAAc,CAAC,CAAC;oBACzB;kBACJ,CAAC,CAAC;kBAEFrC,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,mCAAmC,EAAE,UAACvF,SAAS,EAAEoG,SAAS,EAAElU,KAAK,EAAEqV,UAAU,EAAExD,UAAU,EAAK;oBAC7G,IAAI,CAACY,MAAI,CAAC0C,6BAA6B,EAAE;sBACrC1C,MAAI,CAACyC,SAAS,CAAC,CAAC;sBAChBzC,MAAI,CAAC6C,mBAAmB,CAAC,CAAC;;sBAE1B;sBACA,KAAK,IAAIjH,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGoE,MAAI,CAAC1N,QAAQ,CAAC3P,MAAM,EAAEiZ,CAAC,EAAE,EAAE;wBAC3C,IAAIoE,MAAI,CAAC1N,QAAQ,CAACsJ,CAAC,CAAC,CAAC1J,WAAW,EAAE;0BAC9B8N,MAAI,CAAC1N,QAAQ,CAACsJ,CAAC,CAAC,CAAC1J,WAAW,GAAG,KAAK;wBACxC;sBACJ;sBAEA,IAAI4Q,QAAQ,GAAG9C,MAAI,CAAC1N,QAAQ,CAAC3P,MAAM;sBACnC,IAAIogB,UAAU,GAAG;wBACbnB,EAAE,EAAEH,SAAS;wBACbhN,IAAI,EAAE,WAAW;wBACjBxE,OAAO,EAAE,EAAE;wBACXkS,WAAW,EAAE,EAAE;wBACfjQ,WAAW,EAAE,IAAI;wBACjBwP,UAAU,EAAE,IAAI;wBAChBtC,UAAU,EAAEY,MAAI,CAACb,4BAA4B,CAACC,UAAU;sBAC5D,CAAC;sBACDY,MAAI,CAAC1N,QAAQ,CAACtM,IAAI,CAAC+c,UAAU,CAAC;sBAC9B/C,MAAI,CAAC0C,6BAA6B,GAAG;wBAAEzY,KAAK,EAAE6Y,QAAQ;wBAAE7S,OAAO,EAAE;sBAAG,CAAC;oBACzE;oBAEA+P,MAAI,CAAC0C,6BAA6B,CAACzS,OAAO,IAAI1C,KAAK;oBACnD,IAAIwT,GAAG,GAAGf,MAAI,CAAC1N,QAAQ,CAAC0N,MAAI,CAAC0C,6BAA6B,CAACzY,KAAK,CAAC;oBACjE,IAAI8W,GAAG,EAAE;sBACL,IAAI,CAACA,GAAG,CAAC3B,UAAU,EAAE;wBACjB2B,GAAG,CAAC3B,UAAU,GAAGY,MAAI,CAACb,4BAA4B,CAACC,UAAU,CAAC;sBAClE;sBACA2B,GAAG,CAAC9Q,OAAO,GAAG+P,MAAI,CAAC0C,6BAA6B,CAACzS,OAAO;sBACxD8Q,GAAG,CAACoB,WAAW,GAAGnS,oBAAoB,CAAC+Q,GAAG,CAAC9Q,OAAO,EAAE8Q,GAAG,CAAC;sBACxDf,MAAI,CAACiB,SAAS,CAAC,YAAM;wBACjBjT,qBAAqB,CAAC+S,GAAG,CAAC;wBAC1Bf,MAAI,CAACqC,cAAc,CAAC,CAAC;sBACzB,CAAC,CAAC;oBACN;kBACJ,CAAC,CAAC;kBAEFrC,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,sCAAsC,EAAE,UAACvF,SAAS,EAAEoG,SAAS,EAAK;oBACjF,IAAIzB,MAAI,CAAC0C,6BAA6B,EAAE;sBACpC,IAAI3B,GAAG,GAAGf,MAAI,CAAC1N,QAAQ,CAAC0N,MAAI,CAAC0C,6BAA6B,CAACzY,KAAK,CAAC;sBACjE,IAAI8W,GAAG,EAAE;wBACLA,GAAG,CAAC7O,WAAW,GAAG,KAAK;sBAC3B;sBACA8N,MAAI,CAAC0C,6BAA6B,GAAG,IAAI;oBAC7C;kBACJ,CAAC,CAAC;kBAEF1C,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,mBAAmB,EAAE,UAACvF,SAAS,EAAE2H,WAAW,EAAEC,WAAW,EAAK;oBAC7E,IAAID,WAAW,EAAE;sBACb,IAAME,YAAY,GAAGC,IAAI,CAACH,WAAW,CAAC;sBACtC,IAAMpF,KAAK,GAAG,IAAIwF,UAAU,CAACF,YAAY,CAACvgB,MAAM,CAAC;sBACjD,KAAK,IAAIhB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGuhB,YAAY,CAACvgB,MAAM,EAAEhB,CAAC,EAAE,EAAE;wBAC1Cic,KAAK,CAACjc,CAAC,CAAC,GAAGuhB,YAAY,CAACG,UAAU,CAAC1hB,CAAC,CAAC;sBACzC;sBACAqe,MAAI,CAACxM,WAAW,CAACxN,IAAI,CAAC4X,KAAK,CAAC;oBAChC;kBACJ,CAAC,CAAC;kBAEFoC,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,sBAAsB,EAAE,UAACvF,SAAS,EAAK;oBACtD2E,MAAI,CAACsD,kBAAkB,CAAC,CAAC;kBAC7B,CAAC,CAAC;kBAEFtD,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,qBAAqB,EAAE,UAAC2C,YAAY,EAAK;oBACxDvD,MAAI,CAACwD,mBAAmB,CAACD,YAAY,CAAC;kBAC1C,CAAC,CAAC;kBAEFvD,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,oBAAoB,EAAE,UAAC2C,YAAY,EAAK;oBACvDvD,MAAI,CAACyD,kBAAkB,CAACF,YAAY,CAAC;kBACzC,CAAC,CAAC;kBAEFvD,MAAI,CAACI,UAAU,CAACQ,EAAE,CAAC,oBAAoB,EAAE,UAAC8C,gBAAgB,EAAK;oBAC3D1D,MAAI,CAAC2D,kBAAkB,CAACD,gBAAgB,CAAC;kBAC7C,CAAC,CAAC;kBAEF1D,MAAI,CAACI,UAAU,CAACwD,cAAc,CAAC,YAAM;oBACjCjV,OAAO,CAACC,IAAI,CAAC,0BAA0B,CAAC;kBAC5C,CAAC,CAAC;kBAEFoR,MAAI,CAACI,UAAU,CAACyD,aAAa,CAAC,YAAM;oBAChClV,OAAO,CAACmV,IAAI,CAAC,uBAAuB,CAAC;oBAErC,IAAI9D,MAAI,CAAC1O,gBAAgB,EAAE;sBACvB0O,MAAI,CAAC+D,oBAAoB,CAAC,CAAC;oBAC/B,CAAC,MAAM,IAAIvW,MAAM,CAACwW,iBAAiB,EAAE;sBACjChE,MAAI,CAACwB,eAAe,CAAC,CAAC;oBAC1B;kBACJ,CAAC,CAAC;kBAEFxB,MAAI,CAACI,UAAU,CAAC6D,OAAO,CAAC,UAACvU,KAAK,EAAK;oBAC/B,IAAIsQ,MAAI,CAAC7N,gBAAgB,EAAE;sBACvB;oBACJ;oBAEA,IAAIzC,KAAK,EAAE;sBACPf,OAAO,CAACC,IAAI,CAAC,uCAAuC,EAAEc,KAAK,CAACzB,OAAO,IAAIyB,KAAK,CAAC;oBACjF;kBACJ,CAAC,CAAC;kBAACyQ,SAAA,CAAA/d,CAAA;kBAAA+d,SAAA,CAAA5e,CAAA;kBAAA,OAGOye,MAAI,CAACI,UAAU,CAAC1T,KAAK,CAAC,CAAC;gBAAA;kBAAAyT,SAAA,CAAA5e,CAAA;kBAAA;gBAAA;kBAAA4e,SAAA,CAAA/d,CAAA;kBAAA8d,GAAA,GAAAC,SAAA,CAAA5d,CAAA;kBAE7BoM,OAAO,CAACe,KAAK,CAAC,4BAA4B,EAAAwQ,GAAK,CAAC;gBAAC;kBAAA,OAAAC,SAAA,CAAA3d,CAAA;cAAA;YAAA,GAAAyd,QAAA;UAAA;QAEzD,CAAC;QACDiE,kBAAkB,WAAlBA,kBAAkBA,CAACjW,OAAO,EAAE;UAAA,IAAAkW,MAAA;UACxB,IAAIlW,OAAO,CAACwG,IAAI,KAAK,WAAW,EAAE;YAC9BxG,OAAO,CAACmR,UAAU,GAAG,IAAI,CAACD,4BAA4B,CAAClR,OAAO,CAACmR,UAAU,CAAC;UAC9E;UAEA,IAAInR,OAAO,CAACgC,OAAO,IAAI,CAAChC,OAAO,CAACkU,WAAW,EAAE;YACzClU,OAAO,CAACkU,WAAW,GAAGnS,oBAAoB,CAAC/B,OAAO,CAACgC,OAAO,EAAEhC,OAAO,CAAC;UACxE;UACA,IAAI,CAACmW,SAAS,CAAC,IAAIC,WAAW,CAAC,2BAA2B,EAAE;YAAEnF,MAAM,EAAE;cAAEjR,OAAO,EAAEA;YAAQ;UAAE,CAAC,CAAC,CAAC;UAC9F,IAAI,CAACqE,QAAQ,CAACtM,IAAI,CAACiI,OAAO,CAAC;UAE3B,IAAI,CAACgT,SAAS,CAAC,YAAM;YACjBkD,MAAI,CAACC,SAAS,CAAC,IAAIC,WAAW,CAAC,0BAA0B,EAAE;cAAEnF,MAAM,EAAE;gBAAEjR,OAAO,EAAEA;cAAQ;YAAE,CAAC,CAAC,CAAC;UACjG,CAAC,CAAC;QACN,CAAC;QACD+S,UAAU,WAAVA,UAAUA,CAAC/S,OAAO,EAAE;UAAA,IAAAqW,MAAA;UAEhB;UACA,IAAIrW,OAAO,CAACyT,UAAU,KAAK7U,SAAS,EAAE;YAClCoB,OAAO,CAACyT,UAAU,GAAG,IAAI;UAC7B;UAEA,IAAIzT,OAAO,CAACgC,OAAO,EAAE;YACjB,IAAIsU,gBAAgB,GAAGtW,OAAO,CAACgC,OAAO,CAAC3H,IAAI,CAAC,CAAC;YAC7C2F,OAAO,CAAC1D,UAAU,GAAGD,mBAAmB,CAAC2D,OAAO,CAAC1D,UAAU,CAAC;YAE5D,IAAI0D,OAAO,CAAC1D,UAAU,IAAItE,OAAA,CAAOgI,OAAO,CAAC1D,UAAU,MAAK,QAAQ,IAAIvI,MAAM,CAAC+N,IAAI,CAAC9B,OAAO,CAAC1D,UAAU,CAAC,CAAC5H,MAAM,EAAE;cAExG;cACA,IAAM6hB,SAAS,GAAGxiB,MAAM,CAAC0I,OAAO,CAACuD,OAAO,CAAC1D,UAAU,CAAC,CAACka,MAAM,CAAC,UAAAC,KAAA;gBAAA,IAAAC,KAAA,GAAApf,cAAA,CAAAmf,KAAA;kBAAE7Z,GAAG,GAAA8Z,KAAA;gBAAA,OAAMJ,gBAAgB,CAACK,QAAQ,CAAC/Z,GAAG,CAAC;cAAA,EAAC;cAEtG,IAAI2Z,SAAS,CAAC7hB,MAAM,EAAE;gBAClB;gBACA6hB,SAAS,CAACK,IAAI,CAAC,UAAAC,KAAA,EAAAC,KAAA;kBAAA,IAAAC,KAAA,GAAAzf,cAAA,CAAAuf,KAAA;oBAAItiB,CAAC,GAAAwiB,KAAA;kBAAA,IAAAC,KAAA,GAAA1f,cAAA,CAAAwf,KAAA;oBAAMG,CAAC,GAAAD,KAAA;kBAAA,OAAMziB,CAAC,CAACyH,KAAK,GAAGib,CAAC,CAACjb,KAAK;gBAAA,EAAC;;gBAEnD;gBACA,IAAIkb,YAAY,GAAG,CAAC;gBAAC,IAAAC,UAAA,GAAA3gB,0BAAA,CACM+f,SAAS;kBAAAa,MAAA;gBAAA;kBAApC,KAAAD,UAAA,CAAArgB,CAAA,MAAAsgB,MAAA,GAAAD,UAAA,CAAA7jB,CAAA,IAAAwB,IAAA,GAAsC;oBAAA,IAAAuiB,YAAA,GAAA/f,cAAA,CAAA8f,MAAA,CAAAriB,KAAA;sBAA1B6H,GAAG,GAAAya,YAAA;sBAAEtiB,KAAK,GAAAsiB,YAAA;oBAClB,IAAMjU,WAAW,aAAAlG,MAAA,CAAanI,KAAK,CAACiH,KAAK,OAAI;oBAC7Csa,gBAAgB,GAAGA,gBAAgB,CAACgB,UAAU,CAAC1a,GAAG,EAAEwG,WAAW,CAAC;oBAChErO,KAAK,CAACwiB,aAAa,GAAGL,YAAY,EAAE;oBACpCniB,KAAK,CAACyiB,YAAY,GAAGpU,WAAW;kBACpC;;kBAEA;gBAAA,SAAA9C,GAAA;kBAAA6W,UAAA,CAAAjkB,CAAA,CAAAoN,GAAA;gBAAA;kBAAA6W,UAAA,CAAAjjB,CAAA;gBAAA;gBAAA,IAAAujB,UAAA,GAAAjhB,0BAAA,CACwB+f,SAAS;kBAAAmB,MAAA;gBAAA;kBAAjC,KAAAD,UAAA,CAAA3gB,CAAA,MAAA4gB,MAAA,GAAAD,UAAA,CAAAnkB,CAAA,IAAAwB,IAAA,GAAmC;oBAAA,IAAA6iB,YAAA,GAAArgB,cAAA,CAAAogB,MAAA,CAAA3iB,KAAA;sBAArBA,MAAK,GAAA4iB,YAAA;oBACfrB,gBAAgB,GAAGA,gBAAgB,CAACgB,UAAU,CAACviB,MAAK,CAACyiB,YAAY,kBAAAta,MAAA,CAAkBnI,MAAK,CAACwiB,aAAa,oBAAiB,CAAC;kBAC5H;;kBAEA;gBAAA,SAAAjX,GAAA;kBAAAmX,UAAA,CAAAvkB,CAAA,CAAAoN,GAAA;gBAAA;kBAAAmX,UAAA,CAAAvjB,CAAA;gBAAA;gBACAoiB,gBAAgB,GAAGA,gBAAgB,CAACgB,UAAU,CAAC,sBAAsB,EAAE,kCAAkC,CAAC;gBAE1GhB,gBAAgB,IAAI,UAAU;gBAAC,IAAAsB,UAAA,GAAAphB,0BAAA,CAEJ+f,SAAS;kBAAAsB,MAAA;gBAAA;kBAApC,KAAAD,UAAA,CAAA9gB,CAAA,MAAA+gB,MAAA,GAAAD,UAAA,CAAAtkB,CAAA,IAAAwB,IAAA,GAAsC;oBAAA,IAAAgjB,YAAA,GAAAxgB,cAAA,CAAAugB,MAAA,CAAA9iB,KAAA;sBAA1B6H,IAAG,GAAAkb,YAAA;sBAAE/iB,OAAK,GAAA+iB,YAAA;oBAClB,IAAM1G,KAAK,GAAGrc,OAAK,CAACwF,IAAI,IAAIqC,IAAG;oBAC/B0Z,gBAAgB,IAAIvhB,OAAK,CAACoH,IAAI,QAAAe,MAAA,CACnBnI,OAAK,CAACwiB,aAAa,WAAAra,MAAA,CAAQkU,KAAK,QAAAlU,MAAA,CAAKnI,OAAK,CAACoH,IAAI,kBAAAe,MAAA,CAC/CnI,OAAK,CAACwiB,aAAa,UAAAra,MAAA,CAAOkU,KAAK,SAAM;kBACpD;gBAAC,SAAA9Q,GAAA;kBAAAsX,UAAA,CAAA1kB,CAAA,CAAAoN,GAAA;gBAAA;kBAAAsX,UAAA,CAAA1jB,CAAA;gBAAA;cACL;YACJ;YAEA8L,OAAO,CAACgC,OAAO,GAAGsU,gBAAgB;YAClCtW,OAAO,CAACkU,WAAW,GAAGnS,oBAAoB,CAACuU,gBAAgB,EAAEtW,OAAO,CAAC;UACzE;UAEA,IAAI,CAACiW,kBAAkB,CAACjW,OAAO,CAAC;UAChC,IAAI,CAACiU,eAAe,CAAC,CAAC;UAEtB,IAAI,CAACjB,SAAS,CAAC,YAAM;YACjB;YACAjT,qBAAqB,CAACC,OAAO,CAAC;YAC9BqW,MAAI,CAACjC,cAAc,CAAC,CAAC;UACzB,CAAC,CAAC;QACN,CAAC;QACD2D,WAAW,WAAXA,WAAWA,CAAC1T,QAAQ,EAAE;UAAA,IAAA2T,MAAA;UAElB,KAAK,IAAItkB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG2Q,QAAQ,CAAC3P,MAAM,EAAEhB,CAAC,EAAE,EAAE;YACtC,IAAI,CAACuiB,kBAAkB,CAAC5R,QAAQ,CAAC3Q,CAAC,CAAC,CAAC;UACxC;UAEA,IAAI,CAACugB,eAAe,CAAC,CAAC;UACtB,IAAI,CAACjB,SAAS,CAAC,YAAM;YACjBgF,MAAI,CAAC5D,cAAc,CAAC,CAAC;UACzB,CAAC,CAAC;QACN,CAAC;QACDH,eAAe,WAAfA,eAAeA,CAAA,EAAG;UACd,IAAI,IAAI,CAAC7Q,WAAW,EAAE;YAClB,IAAI,CAACA,WAAW,CAACmG,SAAS,CAACC,GAAG,CAAC,QAAQ,CAAC;UAC5C;UACA,IAAI,CAAClG,oBAAoB,GAAG,KAAK;QACrC,CAAC;QACD2U,eAAe,WAAfA,eAAeA,CAAA,EAAG;UACd,IAAI,IAAI,CAAC7U,WAAW,EAAE;YAClB,IAAI,CAACA,WAAW,CAACmG,SAAS,CAACyB,MAAM,CAAC,QAAQ,CAAC;UAC/C;UACA,IAAI,CAAC1H,oBAAoB,GAAG,IAAI;QACpC,CAAC;QACD4U,uBAAuB,WAAvBA,uBAAuBA,CAAA,EAAG;UACtB,OAAO3Y,MAAM,CAAC2Y,uBAAuB,KAAK,KAAK;QACnD,CAAC;QACDC,6BAA6B,WAA7BA,6BAA6BA,CAAA,EAAG;UAC5B,IAAI,IAAI,CAACD,uBAAuB,CAAC,CAAC,EAAE;YAChC,OAAO,IAAI;UACf;UAEA,IAAME,kBAAkB,GAAG7Y,MAAM,CAAC8Y,8BAA8B,IAAI,+CAA+C;UAEnH,IAAI,IAAI,CAACpV,YAAY,EAAE;YACnB,IAAI,CAACA,YAAY,CAACqV,QAAQ,GAAG,IAAI;YACjC,IAAI,CAACrV,YAAY,CAAClO,KAAK,GAAG,EAAE;YAC5B,IAAI,CAACkO,YAAY,CAACG,WAAW,GAAGgV,kBAAkB;UACtD;UAEA,IAAI,IAAI,CAAClV,aAAa,EAAE;YACpB,IAAI,CAACA,aAAa,CAACoV,QAAQ,GAAG,IAAI;UACtC;UAEA,IAAI,IAAI,CAACC,gBAAgB,EAAE;YACvB,IAAI,CAACA,gBAAgB,CAACD,QAAQ,GAAG,IAAI;YACrC,IAAI,CAACC,gBAAgB,CAAC7P,KAAK,CAAC8P,OAAO,GAAG,MAAM;UAChD;UAEA,IAAI,IAAI,CAACC,yBAAyB,EAAE;YAChC,IAAI,CAACA,yBAAyB,CAACH,QAAQ,GAAG,IAAI;YAC9C,IAAI,CAACG,yBAAyB,CAAC/P,KAAK,CAAC8P,OAAO,GAAG,MAAM;UACzD;UAEA,OAAO,KAAK;QAChB,CAAC;QACDrC,SAAS,WAATA,SAASA,CAACvL,KAAK,EAAE;UACbnQ,QAAQ,CAAC6Z,aAAa,CAAC1J,KAAK,CAAC;QACjC,CAAC;QACD8N,WAAW,WAAXA,WAAWA,CAAC1Y,OAAO,EAAE;UACjB,OAAOA,OAAO,CAACwG,IAAI,KAAK,WAAW;QACvC,CAAC;QACD2M,WAAW,WAAXA,WAAWA,CAAA,EAAG;UACV,IAAI,CAAC,IAAI,CAACgF,6BAA6B,CAAC,CAAC,EAAE;YACvC;UACJ;UAEA,IAAIQ,aAAa,GAAG,IAAI,CAACpU,MAAM,CAAClK,IAAI,CAAC,CAAC;UAEtC,IAAI,CAACse,aAAa,EAAE;YAChB;UACJ;;UAEA;UACA,IAAI,IAAI,CAAC5T,WAAW,EAAE;YAClB,IAAI,CAACqO,aAAa,CAAC,CAAC;UACxB;;UAEA;UACA,IAAI,CAACiB,eAAe,GAAG,IAAI;;UAE3B;UACA,IAAI,IAAI,CAACpO,kBAAkB,EAAE;YACzB,IAAI,CAAC5B,QAAQ,CAACmL,MAAM,CAAC,CAAC,EAAE,IAAI,CAACnL,QAAQ,CAAC3P,MAAM,CAAC;UACjD;UAEA,IAAI,CAACqe,UAAU,CAAC;YACZvM,IAAI,EAAE,MAAM;YACZxE,OAAO,EAAE2W;UACb,CAAC,CAAC;UAEF,IAAI,CAACC,aAAa,CAAC,IAAI,CAAC5K,YAAY,CAAC,CAAC,EAAE2K,aAAa,EAAE,IAAI,CAAC;UAC5D,IAAI,CAAC1V,YAAY,CAAClO,KAAK,GAAG,EAAE;UAC5B,IAAI,CAACwP,MAAM,GAAG,EAAE;QACpB,CAAC;QACDsU,cAAc,WAAdA,cAAcA,CAAA,EAAG;UAAA,IAAAC,MAAA;UACb,IAAI,IAAI,CAAC/T,WAAW,IAAI,CAAC,IAAI,CAACoN,UAAU,EAAE;YACtC;UACJ;UAEA4G,SAAS,CAACC,YAAY,CAACC,YAAY,CAAC;YAAEC,KAAK,EAAE;cAAEC,gBAAgB,EAAE,IAAI;cAAEC,gBAAgB,EAAE,IAAI;cAAEC,eAAe,EAAE;YAAK;UAAE,CAAC,CAAC,CACpHnjB,IAAI,CAAC,UAAAkO,MAAM,EAAI;YACZ,IAAIkV,QAAQ,GAAGC,aAAa,CAACC,eAAe,CAAC,uBAAuB,CAAC,GAC/D,uBAAuB,GACvBD,aAAa,CAACC,eAAe,CAAC,wBAAwB,CAAC,GACnD,wBAAwB,GACxB,YAAY;YAEtBV,MAAI,CAAC9T,aAAa,GAAG,IAAIuU,aAAa,CAACnV,MAAM,EAAE;cAC3CkV,QAAQ,EAAEA,QAAQ;cAClBG,kBAAkB,EAAE;YACxB,CAAC,CAAC;YAEFX,MAAI,CAAC7T,kBAAkB,GAAG6T,MAAI,CAACvU,MAAM;YACrCuU,MAAI,CAACzE,eAAe,GAAG,KAAK;YAE5B,IAAIqF,OAAO,GAAG,IAAItH,OAAO,CAACuH,OAAO,CAAC,CAAC;YACnC,IAAItM,SAAS,GAAGyL,MAAI,CAAC9K,YAAY,CAAC,CAAC;YACnC,IAAIZ,SAAS,GAAG0L,MAAI,CAAC/K,YAAY,CAAC,CAAC,IAAI,EAAE;YACzC,IAAI6L,YAAY,GAAG5jB,OAAO,CAACC,OAAO,CAAC,CAAC;YAEpC6iB,MAAI,CAAC9T,aAAa,CAAC0G,gBAAgB,CAAC,eAAe,EAAE,UAACxY,CAAC,EAAK;cACxD,IAAIA,CAAC,CAAC8J,IAAI,IAAI9J,CAAC,CAAC8J,IAAI,CAAC6c,IAAI,GAAG,CAAC,EAAE;gBAC3BD,YAAY,GAAGA,YAAY,CAAC1jB,IAAI,cAAAC,iBAAA,cAAAb,YAAA,GAAAE,CAAA,CAAC,SAAAskB,SAAA;kBAAA,IAAA9c,IAAA,EAAA+c,UAAA,EAAA9E,YAAA,EAAA+E,MAAA;kBAAA,OAAA1kB,YAAA,GAAAC,CAAA,WAAA0kB,SAAA;oBAAA,kBAAAA,SAAA,CAAA3mB,CAAA;sBAAA;wBAAA2mB,SAAA,CAAA3mB,CAAA;wBAAA,OACZJ,CAAC,CAAC8J,IAAI,CAACkd,WAAW,CAAC,CAAC;sBAAA;wBAAjCld,IAAI,GAAAid,SAAA,CAAA3lB,CAAA;wBACJylB,UAAU,GAAG,IAAI5E,UAAU,CAACnY,IAAI,CAAC;wBACjCiY,YAAY,GAAG8E,UAAU,CAACI,MAAM,CAAC,UAAUC,GAAG,EAAEC,KAAI,EAAE;0BAAE,OAAOD,GAAG,GAAGE,MAAM,CAACC,YAAY,CAACF,KAAI,CAAC;wBAAE,CAAC,EAAE,EAAE,CAAC;wBACtGL,MAAM,GAAGQ,IAAI,CAACvF,YAAY,CAAC;wBAC/ByE,OAAO,CAAC3iB,IAAI,CAACijB,MAAM,CAAC;sBAAC;wBAAA,OAAAC,SAAA,CAAA1lB,CAAA;oBAAA;kBAAA,GAAAulB,QAAA;gBAAA,CACxB,GAAC;cACN;YACJ,CAAC,CAAC;YAEFhB,MAAI,CAAC9T,aAAa,CAAC0G,gBAAgB,CAAC,MAAM,EAAE,YAAM;cAC9CtH,MAAM,CAACqW,SAAS,CAAC,CAAC,CAAC5H,OAAO,CAAC,UAAA6H,KAAK;gBAAA,OAAIA,KAAK,CAACC,IAAI,CAAC,CAAC;cAAA,EAAC;cACjDf,YAAY,CAAC1jB,IAAI,CAAC;gBAAA,OAAMwjB,OAAO,CAACkB,QAAQ,CAAC,CAAC;cAAA,EAAC;YAC/C,CAAC,CAAC;YAEF,IAAInd,QAAQ,GAAGsb,SAAS,CAACtb,QAAQ,IAAIhD,QAAQ,CAACogB,eAAe,CAACzd,IAAI,IAAI,OAAO;YAC7E0b,MAAI,CAAC3G,UAAU,CAAC2I,IAAI,CAAC,iBAAiB,EAAEzN,SAAS,EAAED,SAAS,EAAEsM,OAAO,EAAEJ,QAAQ,EAAE7b,QAAQ,CAAC;YAC1Fqb,MAAI,CAAC9T,aAAa,CAACvG,KAAK,CAAC,GAAG,CAAC;YAC7Bqa,MAAI,CAAC/T,WAAW,GAAG,IAAI;YACvB+T,MAAI,CAACiC,eAAe,CAAC,CAAC;UAC1B,CAAC,CAAC,SACI,CAAC,UAAAza,GAAG,EAAI;YACVI,OAAO,CAACe,KAAK,CAAC,2BAA2B,EAAEnB,GAAG,CAAC;UACnD,CAAC,CAAC;QACV,CAAC;QACD8S,aAAa,WAAbA,aAAaA,CAAA,EAAG;UACZ,IAAI,CAAC,IAAI,CAACrO,WAAW,IAAI,CAAC,IAAI,CAACC,aAAa,EAAE;YAC1C;UACJ;UAEA,IAAI,CAACA,aAAa,CAAC2V,IAAI,CAAC,CAAC;UACzB,IAAI,CAAC5V,WAAW,GAAG,KAAK;UACxB,IAAI,CAACgW,eAAe,CAAC,CAAC;QAC1B,CAAC;QACDC,eAAe,WAAfA,eAAeA,CAAA,EAAG;UACd,IAAI,IAAI,CAACjW,WAAW,EAAE;YAClB,IAAI,CAACqO,aAAa,CAAC,CAAC;UACxB,CAAC,MAAM;YACH,IAAI,CAACyF,cAAc,CAAC,CAAC;UACzB;QACJ,CAAC;QACDkC,eAAe,WAAfA,eAAeA,CAAA,EAAG;UACd,IAAI,CAAC,IAAI,CAAC7V,SAAS,EAAE;YACjB;UACJ;UAEA,IAAI,IAAI,CAACH,WAAW,EAAE;YAClB,IAAI,CAACG,SAAS,CAACqE,SAAS,CAACC,GAAG,CAAC,eAAe,CAAC;YAC7C,IAAI,CAACtE,SAAS,CAACtK,SAAS,GAAG,kCAAkC;UACjE,CAAC,MAAM;YACH,IAAI,CAACsK,SAAS,CAACqE,SAAS,CAACyB,MAAM,CAAC,eAAe,CAAC;YAChD,IAAI,CAAC9F,SAAS,CAACtK,SAAS,GAAG,wCAAwC;UACvE;QACJ,CAAC;QACDge,aAAa,WAAbA,aAAaA,CAACvL,SAAS,EAAEsL,aAAa,EAAEsC,gBAAgB,EAAE;UAAA,IAAAC,MAAA;UAEtD,IAAI,IAAI,CAAC9W,MAAM,EAAE;YACb,IAAI,CAACA,MAAM,CAAC+W,OAAO,CAAC,CAAC;YACrB,IAAI,CAAC/W,MAAM,GAAG,IAAI;UACtB;UAEA,IAAI,CAACgX,gBAAgB,CAAC,CAAC;UACvB,IAAI,CAACC,mBAAmB,CAAC,CAAC;UAC1B,IAAI,CAAClX,UAAU,GAAG,IAAI;UAEtB,IAAInC,OAAO,GAAG,EAAE;UAChB,IAAI1F,UAAU,GAAG,CAAC,CAAC;UACnB,IAAIgf,cAAc,GAAG,IAAI;;UAEzB;UACA,IAAIC,YAAY,GAAG,IAAI,CAAClX,QAAQ,CAAC3P,MAAM;UACvC,IAAI8mB,gBAAgB,GAAG,IAAI,CAACzN,YAAY,CAAC,CAAC;UAE1C,IAAI,CAAC3J,MAAM,GAAG,IAAI,CAAC+N,UAAU,CAAC/N,MAAM,CAAC,aAAa,EAAEiJ,SAAS,EAAEsL,aAAa,EAAE6C,gBAAgB,EAAEP,gBAAgB,CAAC,CAC5GQ,SAAS,CAAC;YACP1kB,IAAI,EAAE,SAANA,IAAIA,CAAG2kB,KAAK,EAAK;cACb,IAAI1b,OAAO,GAAGkb,MAAI,CAAC7W,QAAQ,CAACkX,YAAY,CAAC;cAEzC,IAAI,CAACvb,OAAO,EAAE;gBAEV,IAAI0b,KAAK,CAACtO,SAAS,IAAI,CAACoO,gBAAgB,EAAE;kBACtCN,MAAI,CAACxM,iBAAiB,CAACgN,KAAK,CAACtO,SAAS,CAAC;gBAC3C;gBAEA8N,MAAI,CAACtG,mBAAmB,CAAC,CAAC;gBAC1B;gBACA2G,YAAY,GAAGL,MAAI,CAAC7W,QAAQ,CAAC3P,MAAM;gBACnC,IAAIogB,UAAU,GAAG;kBACbnB,EAAE,EAAE+H,KAAK,CAAClI,SAAS;kBACnBhN,IAAI,EAAE,WAAW;kBACjBwK,KAAK,EAAE0K,KAAK,CAAC1K,KAAK;kBAClBhP,OAAO,EAAE,EAAE;kBACXkS,WAAW,EAAE,EAAE;kBACfjQ,WAAW,EAAE,IAAI;kBACjBwP,UAAU,EAAE;gBAChB,CAAC;gBAEDyH,MAAI,CAAC7W,QAAQ,CAACtM,IAAI,CAAC+c,UAAU,CAAC;gBAE9B9U,OAAO,GAAG8U,UAAU;cACxB;cAEA,IAAI4G,KAAK,CAAC1K,KAAK,KAAK,CAAChR,OAAO,CAACgR,KAAK,IAAIhR,OAAO,CAACgR,KAAK,KAAK0K,KAAK,CAAC1K,KAAK,CAAC,EAAE;gBAClEhR,OAAO,CAACgR,KAAK,GAAG0K,KAAK,CAAC1K,KAAK;cAC/B;cAEA,IAAI0K,KAAK,CAACpf,UAAU,IAAItE,OAAA,CAAO0jB,KAAK,CAACpf,UAAU,MAAK,QAAQ,IAAIvI,MAAM,CAAC+N,IAAI,CAAC4Z,KAAK,CAACpf,UAAU,CAAC,CAAC5H,MAAM,EAAE;gBAElG,SAAAinB,GAAA,MAAAC,gBAAA,GAA2B7nB,MAAM,CAAC0I,OAAO,CAACif,KAAK,CAACpf,UAAU,CAAC,EAAAqf,GAAA,GAAAC,gBAAA,CAAAlnB,MAAA,EAAAinB,GAAA,IAAE;kBAAA,IAAAE,oBAAA;kBAAxD,IAAAC,mBAAA,GAAAxkB,cAAA,CAAAskB,gBAAA,CAAAD,GAAA;oBAAO/e,GAAG,GAAAkf,mBAAA;oBAAE/mB,KAAK,GAAA+mB,mBAAA;kBAClBxf,UAAU,CAACM,GAAG,CAAC,IAAAif,oBAAA,GAAGvgB,kBAAkB,CAACvG,KAAK,CAAC,cAAA8mB,oBAAA,cAAAA,oBAAA,GAAI,CAAC,CAAC;gBACrD;cACJ;cAEA,IAAIH,KAAK,CAAC1Z,OAAO,EAAE;gBAEf;gBACA;gBACA,IAAI0Z,KAAK,CAAC/G,UAAU,IAAI2G,cAAc,IAAII,KAAK,CAAC/G,UAAU,KAAK2G,cAAc,EAAE;kBAC3EtZ,OAAO,IAAI,MAAM;gBACrB;gBAEA,IAAI0Z,KAAK,CAAC/G,UAAU,EAAE;kBAClB2G,cAAc,GAAGI,KAAK,CAAC/G,UAAU;gBACrC;gBAEA,IAAI2B,gBAAgB,GAAGoF,KAAK,CAAC1Z,OAAO;gBAEpC,SAAA+Z,GAAA,MAAAC,gBAAA,GAA2BjoB,MAAM,CAAC0I,OAAO,CAACH,UAAU,CAAC,EAAAyf,GAAA,GAAAC,gBAAA,CAAAtnB,MAAA,EAAAqnB,GAAA,IAAE;kBAAlD,IAAAE,mBAAA,GAAA3kB,cAAA,CAAA0kB,gBAAA,CAAAD,GAAA;oBAAOnf,KAAG,GAAAqf,mBAAA;oBAAElnB,OAAK,GAAAknB,mBAAA;kBAClB3F,gBAAgB,GAAGA,gBAAgB,CAACgB,UAAU,CAAC1a,KAAG,kBAAAM,MAAA,CAAkBnI,OAAK,CAACiH,KAAK,oBAAiB,CAAC;gBACrG;;gBAEA;gBACA;gBACAgG,OAAO,IAAIsU,gBAAgB,CAACgB,UAAU,CAAC,sBAAsB,EAAE,kCAAkC,CAAC;cACtG;;cAEA;cACAtX,OAAO,CAACgC,OAAO,GAAGA,OAAO;cAEzBhC,OAAO,CAACkU,WAAW,GAAGnS,oBAAoB,CAACC,OAAO,EAAEhC,OAAO,CAAC;cAE5Dkb,MAAI,CAAC7W,QAAQ,CAACkX,YAAY,CAAC,GAAGvb,OAAO;cAErCkb,MAAI,CAAClI,SAAS,CAAC,YAAM;gBACjBjT,qBAAqB,CAACC,OAAO,CAAC;gBAC9Bkb,MAAI,CAAC9G,cAAc,CAAC,CAAC;cACzB,CAAC,CAAC;YACN,CAAC;YACDwG,QAAQ,EAAE,SAAVA,QAAQA,CAAA,EAAQ;cAAA,IAAAsB,aAAA;cACZhB,MAAI,CAACiB,iBAAiB,CAAC7f,UAAU,EAAEif,YAAY,CAAC;cAChDL,MAAI,CAACkB,iBAAiB,CAAC,CAAC;cAExB,IAAItJ,GAAG,GAAGoI,MAAI,CAAC7W,QAAQ,CAACkX,YAAY,CAAC;cACrC,IAAIzI,GAAG,EAAE;gBACLA,GAAG,CAAC7O,WAAW,GAAG,KAAK;cAC3B;cAEA,IAAI,CAAC6O,GAAG,IAAI,CAACA,GAAG,CAAC9Q,OAAO,EAAE;gBACtB;gBACAkZ,MAAI,CAACtG,mBAAmB,CAAC,CAAC;cAC9B;;cAEA;cACA,IAAIsG,MAAI,CAAC9U,kBAAkB,IAAI8U,MAAI,CAAC7V,mBAAmB,IAAIyN,GAAG,IAAIA,GAAG,CAAC9Q,OAAO,EAAE;gBAC3EkZ,MAAI,CAACmB,gBAAgB,CAACvJ,GAAG,CAAC9Q,OAAO,CAAC;cACtC;cAEA,CAAAka,aAAA,GAAAhB,MAAI,CAAC9W,MAAM,cAAA8X,aAAA,eAAXA,aAAA,CAAaf,OAAO,CAAC,CAAC;cACtBD,MAAI,CAAC9W,MAAM,GAAG,IAAI;YACtB,CAAC;YACD3C,KAAK,EAAE,SAAPA,KAAKA,CAAGnB,GAAG,EAAK;cAAA,IAAAgc,cAAA;cACZpB,MAAI,CAACiB,iBAAiB,CAAC7f,UAAU,EAAEif,YAAY,CAAC;cAChDL,MAAI,CAACkB,iBAAiB,CAAC,CAAC;cAExB,IAAItJ,GAAG,GAAGoI,MAAI,CAAC7W,QAAQ,CAACkX,YAAY,CAAC;cACrC,IAAIzI,GAAG,EAAE;gBACLA,GAAG,CAAC7O,WAAW,GAAG,KAAK;cAC3B;cAEAiX,MAAI,CAACtG,mBAAmB,CAAC,CAAC;cAE1B,IAAI,CAACsG,MAAI,CAAChX,gBAAgB,EAAE;gBACxBgX,MAAI,CAACnI,UAAU,CAACmI,MAAI,CAACqB,qBAAqB,CAAC,CAAC,CAAC;cACjD;cAEA,CAAAD,cAAA,GAAApB,MAAI,CAAC9W,MAAM,cAAAkY,cAAA,eAAXA,cAAA,CAAanB,OAAO,CAAC,CAAC;cACtBD,MAAI,CAAC9W,MAAM,GAAG,IAAI;cAElB1D,OAAO,CAACe,KAAK,CAAC,eAAe,EAAEnB,GAAG,CAAC;YACvC;UACJ,CAAC,CAAC;QACV,CAAC;QACDic,qBAAqB,WAArBA,qBAAqBA,CAAA,EAAG;UACpB,IAAIzH,UAAU,GAAG;YACbtO,IAAI,EAAE,WAAW;YACjBxE,OAAO,EAAE,mGAAmG;YAC5GkS,WAAW,EAAE;UACjB,CAAC;UAED,OAAOY,UAAU;QACrB,CAAC;QACDqH,iBAAiB,WAAjBA,iBAAiBA,CAAC7f,UAAU,EAAEif,YAAY,EAAE;UAAA,IAAAiB,MAAA;UACxClgB,UAAU,GAAGD,mBAAmB,CAACC,UAAU,CAAC;UAE5C,IAAIvI,MAAM,CAAC+N,IAAI,CAACxF,UAAU,CAAC,CAAC5H,MAAM,EAAE;YAEhC,IAAIsL,OAAO,GAAG,IAAI,CAACqE,QAAQ,CAACkX,YAAY,CAAC;YACzC,IAAMvZ,OAAO,GAAGhC,OAAO,CAACgC,OAAO,IAAI,EAAE;;YAErC;YACA;YACA,IAAMuU,SAAS,GAAGxiB,MAAM,CAAC0I,OAAO,CAACH,UAAU,CAAC,CAACka,MAAM,CAAC,UAAAiG,KAAA;cAAA,IAAAC,MAAA,GAAAplB,cAAA,CAAAmlB,KAAA;gBAAE7f,GAAG,GAAA8f,MAAA;gBAAE3nB,KAAK,GAAA2nB,MAAA;cAAA,OAC5D1a,OAAO,CAAC2U,QAAQ,CAAC/Z,GAAG,CAAC,IAAIoF,OAAO,CAAC2U,QAAQ,iBAAAzZ,MAAA,CAAiBnI,KAAK,CAACiH,KAAK,oBAAiB,CAAC;YAAA,CAC3F,CAAC;YAED,IAAI,CAACua,SAAS,CAAC7hB,MAAM,EAAE;cACnB;YACJ;;YAEA;YACA6hB,SAAS,CAACK,IAAI,CAAC,UAAA+F,MAAA,EAAAC,MAAA;cAAA,IAAAC,MAAA,GAAAvlB,cAAA,CAAAqlB,MAAA;gBAAIpoB,CAAC,GAAAsoB,MAAA;cAAA,IAAAC,MAAA,GAAAxlB,cAAA,CAAAslB,MAAA;gBAAM3F,CAAC,GAAA6F,MAAA;cAAA,OAAMvoB,CAAC,CAACyH,KAAK,GAAGib,CAAC,CAACjb,KAAK;YAAA,EAAC;;YAEnD;YACA,IAAI+gB,SAAS,GAAG/a,OAAO,CAAC3H,IAAI,CAAC,CAAC;YAC9B,IAAI6c,YAAY,GAAG,CAAC;YAAC,IAAA8F,UAAA,GAAAxmB,0BAAA,CACM+f,SAAS;cAAA0G,MAAA;YAAA;cAApC,KAAAD,UAAA,CAAAlmB,CAAA,MAAAmmB,MAAA,GAAAD,UAAA,CAAA1pB,CAAA,IAAAwB,IAAA,GAAsC;gBAAA,IAAAooB,YAAA,GAAA5lB,cAAA,CAAA2lB,MAAA,CAAAloB,KAAA;kBAA1B6H,GAAG,GAAAsgB,YAAA;kBAAEnoB,KAAK,GAAAmoB,YAAA;gBAClB,IAAM9Z,WAAW,aAAAlG,MAAA,CAAanI,KAAK,CAACiH,KAAK,OAAI;gBAC7C+gB,SAAS,GAAGA,SAAS,CAACzF,UAAU,CAAC1a,GAAG,EAAEwG,WAAW,CAAC;gBAClD2Z,SAAS,GAAGA,SAAS,CAACzF,UAAU,iBAAApa,MAAA,CAAiBnI,KAAK,CAACiH,KAAK,sBAAmBoH,WAAW,CAAC;gBAC3FrO,KAAK,CAACwiB,aAAa,GAAGL,YAAY,EAAE;gBACpCniB,KAAK,CAACyiB,YAAY,GAAGpU,WAAW;cACpC;;cAEA;YAAA,SAAA9C,GAAA;cAAA0c,UAAA,CAAA9pB,CAAA,CAAAoN,GAAA;YAAA;cAAA0c,UAAA,CAAA9oB,CAAA;YAAA;YAAA,IAAAipB,UAAA,GAAA3mB,0BAAA,CACwB+f,SAAS;cAAA6G,MAAA;YAAA;cAAjC,KAAAD,UAAA,CAAArmB,CAAA,MAAAsmB,MAAA,GAAAD,UAAA,CAAA7pB,CAAA,IAAAwB,IAAA,GAAmC;gBAAA,IAAAuoB,YAAA,GAAA/lB,cAAA,CAAA8lB,MAAA,CAAAroB,KAAA;kBAArBA,OAAK,GAAAsoB,YAAA;gBACfN,SAAS,GAAGA,SAAS,CAACzF,UAAU,CAACviB,OAAK,CAACyiB,YAAY,kBAAAta,MAAA,CAAkBnI,OAAK,CAACwiB,aAAa,oBAAiB,CAAC;cAC9G;YAAC,SAAAjX,GAAA;cAAA6c,UAAA,CAAAjqB,CAAA,CAAAoN,GAAA;YAAA;cAAA6c,UAAA,CAAAjpB,CAAA;YAAA;YAED6oB,SAAS,GAAGA,SAAS,CAACzF,UAAU,CAAC,sBAAsB,EAAE,kCAAkC,CAAC;YAE5FyF,SAAS,IAAI,UAAU;YAAC,IAAAO,UAAA,GAAA9mB,0BAAA,CAEG+f,SAAS;cAAAgH,MAAA;YAAA;cAApC,KAAAD,UAAA,CAAAxmB,CAAA,MAAAymB,MAAA,GAAAD,UAAA,CAAAhqB,CAAA,IAAAwB,IAAA,GAAsC;gBAAA,IAAA0oB,YAAA,GAAAlmB,cAAA,CAAAimB,MAAA,CAAAxoB,KAAA;kBAA1B6H,KAAG,GAAA4gB,YAAA;kBAAEzoB,OAAK,GAAAyoB,YAAA;gBAClB,IAAMpM,KAAK,GAAGrc,OAAK,CAACwF,IAAI,IAAIqC,KAAG;gBAC/BmgB,SAAS,IAAIhoB,OAAK,CAACoH,IAAI,QAAAe,MAAA,CACZnI,OAAK,CAACwiB,aAAa,WAAAra,MAAA,CAAQkU,KAAK,QAAAlU,MAAA,CAAKnI,OAAK,CAACoH,IAAI,kBAAAe,MAAA,CAC/CnI,OAAK,CAACwiB,aAAa,UAAAra,MAAA,CAAOkU,KAAK,SAAM;cACpD;YAAC,SAAA9Q,GAAA;cAAAgd,UAAA,CAAApqB,CAAA,CAAAoN,GAAA;YAAA;cAAAgd,UAAA,CAAAppB,CAAA;YAAA;YAED8L,OAAO,CAACgC,OAAO,GAAG+a,SAAS;YAC3B/c,OAAO,CAACkU,WAAW,GAAGnS,oBAAoB,CAACgb,SAAS,EAAE/c,OAAO,CAAC;YAE9D,IAAI,CAACqE,QAAQ,CAACkX,YAAY,CAAC,GAAGvb,OAAO;YAErC,IAAI,CAACgT,SAAS,CAAC,YAAM;cACjBjT,qBAAqB,CAACC,OAAO,CAAC;cAC9Bwc,MAAI,CAACpI,cAAc,CAAC,CAAC;YACzB,CAAC,CAAC;UACN;QACJ,CAAC;QACDgH,gBAAgB,WAAhBA,gBAAgBA,CAAA,EAAG;UACf,IAAIqC,QAAQ,GAAG,IAAI,CAACva,aAAa,CAACuN,YAAY,CAAC,gBAAgB,CAAC;UAEhE,IAAIgN,QAAQ,EAAE;YACV,IAAI,CAACva,aAAa,CAACgN,eAAe,CAAChO,SAAS,CAACC,QAAQ,CAACsb,QAAQ,EAAE;cAAEtN,mBAAmB,EAAE;YAAK,CAAC,CAAC,CAAC;UACnG;UAEA,IAAI,IAAI,CAAClN,YAAY,EAAE;YACnB,IAAI,CAACA,YAAY,CAACya,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC;UAC1D;QACJ,CAAC;QACDtB,iBAAiB,WAAjBA,iBAAiBA,CAAA,EAAG;UAChB,IAAIuB,SAAS,GAAG,IAAI,CAACza,aAAa,CAACuN,YAAY,CAAC,iBAAiB,CAAC;UAElE,IAAIkN,SAAS,EAAE;YACX,IAAI,CAACza,aAAa,CAACgN,eAAe,CAAChO,SAAS,CAACC,QAAQ,CAACwb,SAAS,EAAE;cAAExN,mBAAmB,EAAE;YAAK,CAAC,CAAC,CAAC;UACpG;UAEA,IAAI,IAAI,CAAClN,YAAY,EAAE;YACnB,IAAI,CAACA,YAAY,CAAC2a,eAAe,CAAC,UAAU,CAAC;YAC7C,IAAI,CAAC3a,YAAY,CAAC4a,KAAK,CAAC,CAAC;UAC7B;;UAEA;UACA,IAAI,IAAI,CAAC1a,aAAa,EAAE;YACpB,IAAI2a,KAAK,GAAG,IAAI,CAAC3a,aAAa,CAACmN,gBAAgB,CAAC,oBAAoB,CAAC;YACrE,KAAK,IAAI5c,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGoqB,KAAK,CAACppB,MAAM,EAAEhB,CAAC,EAAE,EAAE;cACnCoqB,KAAK,CAACpqB,CAAC,CAAC,CAAC6V,SAAS,CAACyB,MAAM,CAAC,mBAAmB,CAAC;cAC9C8S,KAAK,CAACpqB,CAAC,CAAC,CAAC6V,SAAS,CAACC,GAAG,CAAC,aAAa,CAAC;YACzC;UACJ;;UAEA;UACA,KAAK,IAAI9V,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG,IAAI,CAAC2Q,QAAQ,CAAC3P,MAAM,EAAEhB,CAAC,EAAE,EAAE;YAC3C,IAAI,IAAI,CAAC2Q,QAAQ,CAAC3Q,CAAC,CAAC,CAACuQ,WAAW,EAAE;cAC9B,IAAI,CAACI,QAAQ,CAAC3Q,CAAC,CAAC,CAACuQ,WAAW,GAAG,KAAK;YACxC;UACJ;QACJ,CAAC;QACD8Z,qBAAqB,WAArBA,qBAAqBA,CAAC7qB,CAAC,EAAE;UAAA,IAAA8qB,SAAA;UACrB,IAAI,CAAA9qB,CAAC,aAADA,CAAC,gBAAA8qB,SAAA,GAAD9qB,CAAC,CAAE+d,MAAM,cAAA+M,SAAA,uBAATA,SAAA,CAAWC,QAAQ,MAAK,IAAI,CAAClY,aAAa,EAAE;YAC5C;UACJ;UAEA,IAAI,CAACyO,SAAS,CAAC,KAAK,CAAC;QACzB,CAAC;QACD6H,gBAAgB,WAAhBA,gBAAgBA,CAAC9hB,IAAI,EAAE2jB,UAAU,EAAE;UAAA,IAAAC,MAAA;UAC/B,IAAI,CAAC,IAAI,CAAC9Y,mBAAmB,IAAI,CAAC9K,IAAI,IAAI,CAAC,IAAI,CAAC4X,UAAU,EAAE;YACxD;UACJ;UAEA,IAAI,CAAC5M,WAAW,GAAG,EAAE;UACrB,IAAI,CAACE,cAAc,GAAG,IAAI;UAC1B,IAAI,CAAC2Y,cAAc,GAAGF,UAAU,KAAKtf,SAAS,GAAGsf,UAAU,GAAG,CAAC,CAAC;UAEhE,IAAI,CAAC/L,UAAU,CAACkM,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAACrQ,YAAY,CAAC,CAAC,EAAE,IAAI,CAACD,YAAY,CAAC,CAAC,EAAExT,IAAI,EAAE,IAAI,CAAC+K,YAAY,CAAC,SACnG,CAAC,UAAAhF,GAAG,EAAI;YACVI,OAAO,CAACe,KAAK,CAAC,sBAAsB,EAAEnB,GAAG,CAAC;YAC1C6d,MAAI,CAAC1Y,cAAc,GAAG,KAAK;YAC3B0Y,MAAI,CAACtY,sBAAsB,GAAG,CAAC,CAAC;YAChCsY,MAAI,CAACC,cAAc,GAAG,CAAC,CAAC;UAC5B,CAAC,CAAC;QACV,CAAC;QACDE,gBAAgB,WAAhBA,gBAAgBA,CAACte,OAAO,EAAEhE,KAAK,EAAE;UAC7B,IAAI,IAAI,CAAC6J,sBAAsB,KAAK7J,KAAK,EAAE;YACvC,IAAI,CAACwY,SAAS,CAAC,CAAC;YAChB;UACJ;UAEA,IAAI,CAACA,SAAS,CAAC,KAAK,CAAC;UACrBvc,MAAM,CAACqc,aAAa,CAAC,IAAI8B,WAAW,CAAC,4BAA4B,EAAE;YAC/DnF,MAAM,EAAE;cAAEgN,QAAQ,EAAE,IAAI,CAAClY;YAAc;UAC3C,CAAC,CAAC,CAAC;UACH,IAAI,CAACF,sBAAsB,GAAG7J,KAAK;UAEnC,IAAI,IAAI,CAAC8J,aAAa,CAAC9J,KAAK,CAAC,EAAE;YAC3B,IAAI,CAACuiB,aAAa,CAAC,IAAI,CAACzY,aAAa,CAAC9J,KAAK,CAAC,CAAC;YAC7C;UACJ;UAEA,IAAI,CAACqgB,gBAAgB,CAACrc,OAAO,CAACgC,OAAO,EAAEhG,KAAK,CAAC;QACjD,CAAC;QACDqZ,kBAAkB,WAAlBA,kBAAkBA,CAAA,EAAG;UACjB,IAAI,IAAI,CAAC9P,WAAW,CAAC7Q,MAAM,KAAK,CAAC,EAAE;YAC/B,IAAI,CAAC,IAAI,CAACgR,mBAAmB,IAAI,IAAI,CAACF,cAAc,CAAC9Q,MAAM,KAAK,CAAC,EAAE;cAC/D,IAAI,CAAC+Q,cAAc,GAAG,KAAK;cAC3B,IAAI,CAACI,sBAAsB,GAAG,CAAC,CAAC;YACpC;YACA;UACJ;UAEA,IAAM2Y,WAAW,GAAG,IAAI,CAACjZ,WAAW,CAAC4U,MAAM,CAAC,UAACsE,GAAG,EAAE/C,KAAK;YAAA,OAAK+C,GAAG,GAAG/C,KAAK,CAAChnB,MAAM;UAAA,GAAE,CAAC,CAAC;UAClF,IAAMgqB,QAAQ,GAAG,IAAIvJ,UAAU,CAACqJ,WAAW,CAAC;UAC5C,IAAIG,MAAM,GAAG,CAAC;UAAC,IAAAC,UAAA,GAAApoB,0BAAA,CACK,IAAI,CAAC+O,WAAW;YAAAsZ,MAAA;UAAA;YAApC,KAAAD,UAAA,CAAA9nB,CAAA,MAAA+nB,MAAA,GAAAD,UAAA,CAAAtrB,CAAA,IAAAwB,IAAA,GAAsC;cAAA,IAA3B4mB,KAAK,GAAAmD,MAAA,CAAA9pB,KAAA;cACZ2pB,QAAQ,CAACI,GAAG,CAACpD,KAAK,EAAEiD,MAAM,CAAC;cAC3BA,MAAM,IAAIjD,KAAK,CAAChnB,MAAM;YAC1B;UAAC,SAAA4L,GAAA;YAAAse,UAAA,CAAA1rB,CAAA,CAAAoN,GAAA;UAAA;YAAAse,UAAA,CAAA1qB,CAAA;UAAA;UACD,IAAI,CAACqR,WAAW,GAAG,EAAE;UAErB,IAAMwZ,IAAI,GAAG,IAAIC,IAAI,CAAC,CAACN,QAAQ,CAAC,EAAE;YAAEzf,IAAI,EAAE;UAAY,CAAC,CAAC;UAExD,IAAI,IAAI,CAACmf,cAAc,IAAI,CAAC,EAAE;YAC1B,IAAI,CAACtY,aAAa,CAAC,IAAI,CAACsY,cAAc,CAAC,GAAGW,IAAI;YAC9C,IAAI,CAACX,cAAc,GAAG,CAAC,CAAC;UAC5B;;UAEA;UACA,IAAI,IAAI,CAAC1Y,mBAAmB,EAAE;YAC1B,IAAI,CAACF,cAAc,CAACzN,IAAI,CAACgnB,IAAI,CAAC;YAC9B;UACJ;UAEA,IAAI,CAACR,aAAa,CAACQ,IAAI,CAAC;QAC5B,CAAC;QACDR,aAAa,WAAbA,aAAaA,CAACQ,IAAI,EAAE;UAAA,IAAAE,OAAA;UAChB,IAAM9kB,GAAG,GAAG+kB,GAAG,CAACC,eAAe,CAACJ,IAAI,CAAC;UACrC,IAAM7F,KAAK,GAAG,IAAIkG,KAAK,CAACjlB,GAAG,CAAC;UAE5B,IAAI,CAACwL,eAAe,GAAGxL,GAAG;UAC1B,IAAI,CAACuL,mBAAmB,GAAGwT,KAAK;UAChC,IAAI,CAACzT,cAAc,GAAG,IAAI;UAE1ByT,KAAK,CAACxN,gBAAgB,CAAC,OAAO,EAAE,YAAM;YAClCuT,OAAI,CAACvZ,mBAAmB,GAAG,IAAI;YAC/BuZ,OAAI,CAACtZ,eAAe,GAAG,IAAI;YAC3BuZ,GAAG,CAACG,eAAe,CAACllB,GAAG,CAAC;YACxB8kB,OAAI,CAACK,eAAe,CAAC,CAAC;UAC1B,CAAC,CAAC;UAEFpG,KAAK,CAACxN,gBAAgB,CAAC,OAAO,EAAE,YAAM;YAClCuT,OAAI,CAACvZ,mBAAmB,GAAG,IAAI;YAC/BuZ,OAAI,CAACtZ,eAAe,GAAG,IAAI;YAC3BuZ,GAAG,CAACG,eAAe,CAACllB,GAAG,CAAC;YACxB8kB,OAAI,CAACK,eAAe,CAAC,CAAC;UAC1B,CAAC,CAAC;UAEFpG,KAAK,CAACqG,IAAI,CAAC,CAAC,SAAM,CAAC,UAAAjf,GAAG,EAAI;YACtBI,OAAO,CAACe,KAAK,CAAC,uBAAuB,EAAEnB,GAAG,CAAC;YAC3C2e,OAAI,CAACvZ,mBAAmB,GAAG,IAAI;YAC/BuZ,OAAI,CAACtZ,eAAe,GAAG,IAAI;YAC3BuZ,GAAG,CAACG,eAAe,CAACllB,GAAG,CAAC;YACxB8kB,OAAI,CAACzZ,cAAc,GAAG,EAAE;YACxByZ,OAAI,CAACxZ,cAAc,GAAG,KAAK;YAC3BwZ,OAAI,CAACpZ,sBAAsB,GAAG,CAAC,CAAC;UACpC,CAAC,CAAC;QACN,CAAC;QACDyZ,eAAe,WAAfA,eAAeA,CAAA,EAAG;UACd,IAAI,IAAI,CAAC9Z,cAAc,CAAC9Q,MAAM,GAAG,CAAC,EAAE;YAChC,IAAI8qB,QAAQ,GAAG,IAAI,CAACha,cAAc,CAACia,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAClB,aAAa,CAACiB,QAAQ,CAAC;UAChC,CAAC,MAAM;YACH,IAAI,CAAC/Z,cAAc,GAAG,KAAK;YAC3B,IAAI,CAACI,sBAAsB,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC6Z,4BAA4B,CAAC,CAAC;UACvC;QACJ,CAAC;QACDlL,SAAS,WAATA,SAASA,CAAA,EAAG;UACR,IAAI,IAAI,CAAC9O,mBAAmB,EAAE;YAC1B,IAAI,CAACA,mBAAmB,CAACia,KAAK,CAAC,CAAC;YAChC,IAAI,CAACja,mBAAmB,CAACka,WAAW,GAAG,CAAC;YACxC,IAAI,CAACla,mBAAmB,GAAG,IAAI;UACnC;UACA,IAAI,IAAI,CAACC,eAAe,EAAE;YACtBuZ,GAAG,CAACG,eAAe,CAAC,IAAI,CAAC1Z,eAAe,CAAC;YACzC,IAAI,CAACA,eAAe,GAAG,IAAI;UAC/B;UACA,IAAI,CAACJ,WAAW,GAAG,EAAE;UACrB,IAAI,CAACC,cAAc,GAAG,EAAE;UACxB,IAAI,CAACC,cAAc,GAAG,KAAK;UAC3B,IAAI,CAACI,sBAAsB,GAAG,CAAC,CAAC;QACpC,CAAC;QACDga,sBAAsB,WAAtBA,sBAAsBA,CAAA,EAAG;UACrB,IAAI,IAAI,CAACzZ,kBAAkB,EAAE;YACzB,IAAI,CAAC0Z,oBAAoB,CAAC,CAAC;UAC/B,CAAC,MAAM;YACH,IAAI,CAACC,qBAAqB,CAAC,CAAC;UAChC;QACJ,CAAC;QACDA,qBAAqB,WAArBA,qBAAqBA,CAAA,EAAG;UAAA,IAAAC,OAAA;UACpB,IAAI,CAAC,IAAI,CAAC9Z,uBAAuB,IAAI,IAAI,CAACE,kBAAkB,IAAI,CAAC,IAAI,CAAC+L,UAAU,EAAE;YAC9E;UACJ;UAEA,IAAI,CAAC/L,kBAAkB,GAAG,IAAI;UAC9B,IAAI,CAAC6Z,wBAAwB,CAAC,CAAC;UAC/B,IAAI,CAACpM,8BAA8B,GAAG,EAAE;UACxC,IAAI,CAACY,6BAA6B,GAAG,IAAI;UACzC,IAAI,CAACT,2BAA2B,GAAG,IAAI;;UAEvC;UACA,IAAI,CAAC0B,kBAAkB,CAAC,oBAAoB,CAAC;UAC7CqD,SAAS,CAACC,YAAY,CAACC,YAAY,CAAC;YAAEC,KAAK,EAAE;cAAEC,gBAAgB,EAAE,IAAI;cAAEC,gBAAgB,EAAE,IAAI;cAAEC,eAAe,EAAE;YAAK;UAAE,CAAC,CAAC,CACpHnjB,IAAI,CAAC,UAAAkO,MAAM,EAAI;YACZ,IAAIkV,QAAQ,GAAGC,aAAa,CAACC,eAAe,CAAC,uBAAuB,CAAC,GAC/D,uBAAuB,GACvBD,aAAa,CAACC,eAAe,CAAC,wBAAwB,CAAC,GACnD,wBAAwB,GACxB,YAAY;YAEtBwG,OAAI,CAAChb,aAAa,GAAG,IAAIuU,aAAa,CAACnV,MAAM,EAAE;cAC3CkV,QAAQ,EAAEA,QAAQ;cAClBG,kBAAkB,EAAE;YACxB,CAAC,CAAC;YAEFuG,OAAI,CAACE,oBAAoB,GAAG,IAAI9N,OAAO,CAACuH,OAAO,CAAC,CAAC;YACjDqG,OAAI,CAACG,mBAAmB,GAAG/b,MAAM;;YAEjC;YACA;YACA;YACA;YACA;YACA,IAAIgc,QAAQ,GAAGnoB,MAAM,CAACooB,YAAY,IAAIpoB,MAAM,CAACqoB,kBAAkB;YAC/D,IAAIF,QAAQ,EAAE;cACVJ,OAAI,CAACO,qBAAqB,GAAG,IAAIH,QAAQ,CAAC,CAAC;cAC3CJ,OAAI,CAACQ,qBAAqB,GAAGR,OAAI,CAACO,qBAAqB,CAACE,cAAc,CAAC,CAAC;cACxET,OAAI,CAACQ,qBAAqB,CAACE,OAAO,GAAG,GAAG;cACxC,IAAIC,SAAS,GAAGX,OAAI,CAACO,qBAAqB,CAACK,uBAAuB,CAACxc,MAAM,CAAC;cAC1Euc,SAAS,CAACE,OAAO,CAACb,OAAI,CAACQ,qBAAqB,CAAC;YACjD;YAEA,IAAI5G,YAAY,GAAG5jB,OAAO,CAACC,OAAO,CAAC,CAAC;YACpC,IAAI6qB,QAAQ,GAAGd,OAAI,CAACQ,qBAAqB;YACzC,IAAIO,wBAAwB,GAAG,EAAE;YAEjCf,OAAI,CAAChb,aAAa,CAAC0G,gBAAgB,CAAC,eAAe,EAAE,UAACxY,CAAC,EAAK;cACxD,IAAIA,CAAC,CAAC8J,IAAI,IAAI9J,CAAC,CAAC8J,IAAI,CAAC6c,IAAI,GAAG,CAAC,EAAE;gBAC3B;gBACA;gBACA,IAAImG,OAAI,CAACva,cAAc,IAAIqb,QAAQ,EAAE;kBACjC,IAAIE,QAAQ,GAAG,IAAI7L,UAAU,CAAC2L,QAAQ,CAACG,iBAAiB,CAAC;kBACzDH,QAAQ,CAACI,oBAAoB,CAACF,QAAQ,CAAC;kBACvC,IAAIvC,GAAG,GAAG,CAAC;kBACX,KAAK,IAAI0C,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGH,QAAQ,CAACtsB,MAAM,EAAEysB,CAAC,EAAE,EAAE;oBAAE1C,GAAG,IAAIuC,QAAQ,CAACG,CAAC,CAAC;kBAAE;kBAChE,IAAIC,GAAG,GAAG3C,GAAG,GAAGuC,QAAQ,CAACtsB,MAAM;kBAE/B,IAAI0sB,GAAG,IAAIL,wBAAwB,EAAE;oBACjC;oBACAf,OAAI,CAACxL,SAAS,CAAC,CAAC;kBACpB;gBACJ;;gBAEA;gBACA;gBACA;gBACAoF,YAAY,GAAGA,YAAY,CAAC1jB,IAAI,cAAAC,iBAAA,cAAAb,YAAA,GAAAE,CAAA,CAAC,SAAA6rB,SAAA;kBAAA,IAAArkB,IAAA,EAAA+c,UAAA,EAAA9E,YAAA,EAAA+E,MAAA;kBAAA,OAAA1kB,YAAA,GAAAC,CAAA,WAAA+rB,SAAA;oBAAA,kBAAAA,SAAA,CAAAhuB,CAAA;sBAAA;wBAAAguB,SAAA,CAAAhuB,CAAA;wBAAA,OACZJ,CAAC,CAAC8J,IAAI,CAACkd,WAAW,CAAC,CAAC;sBAAA;wBAAjCld,IAAI,GAAAskB,SAAA,CAAAhtB,CAAA;wBACJylB,UAAU,GAAG,IAAI5E,UAAU,CAACnY,IAAI,CAAC;wBACjCiY,YAAY,GAAG8E,UAAU,CAACI,MAAM,CAAC,UAAUC,GAAG,EAAEC,MAAI,EAAE;0BAAE,OAAOD,GAAG,GAAGE,MAAM,CAACC,YAAY,CAACF,MAAI,CAAC;wBAAE,CAAC,EAAE,EAAE,CAAC;wBACtGL,MAAM,GAAGQ,IAAI,CAACvF,YAAY,CAAC;wBAC/B,IAAI;0BACA+K,OAAI,CAACE,oBAAoB,CAACnpB,IAAI,CAACijB,MAAM,CAAC;wBAC1C,CAAC,CAAC,OAAO1Z,GAAG,EAAE;0BACV;wBAAA;sBACH;wBAAA,OAAAghB,SAAA,CAAA/sB,CAAA;oBAAA;kBAAA,GAAA8sB,QAAA;gBAAA,CACJ,GAAC;cACN;YACJ,CAAC,CAAC;YAEFrB,OAAI,CAAChb,aAAa,CAAC0G,gBAAgB,CAAC,MAAM,EAAE,YAAM;cAC9CtH,MAAM,CAACqW,SAAS,CAAC,CAAC,CAAC5H,OAAO,CAAC,UAAA6H,KAAK;gBAAA,OAAIA,KAAK,CAACC,IAAI,CAAC,CAAC;cAAA,EAAC;cACjDf,YAAY,CAAC1jB,IAAI,CAAC,YAAM;gBACpB,IAAI;kBACA8pB,OAAI,CAACE,oBAAoB,CAACtF,QAAQ,CAAC,CAAC;gBACxC,CAAC,CAAC,OAAOta,GAAG,EAAE;kBACV;gBAAA;cAER,CAAC,CAAC;YACN,CAAC,CAAC;YAEF,IAAI+M,SAAS,GAAG2S,OAAI,CAAChS,YAAY,CAAC,CAAC;YACnC,IAAIZ,SAAS,GAAG4S,OAAI,CAACjS,YAAY,CAAC,CAAC,IAAI,EAAE;YACzC,IAAItQ,QAAQ,GAAGsb,SAAS,CAACtb,QAAQ,IAAIhD,QAAQ,CAACogB,eAAe,CAACzd,IAAI,IAAI,OAAO;YAE7E4iB,OAAI,CAAC7N,UAAU,CAAC2I,IAAI,CAAC,mBAAmB,EAAEzN,SAAS,EAAED,SAAS,EAAE4S,OAAI,CAACE,oBAAoB,EAAE5G,QAAQ,EAAE7b,QAAQ,CAAC;YAC9GuiB,OAAI,CAAChb,aAAa,CAACvG,KAAK,CAAC,GAAG,CAAC;YAC7BuhB,OAAI,CAACjb,WAAW,GAAG,IAAI;UAC3B,CAAC,CAAC,SACI,CAAC,UAAAzE,GAAG,EAAI;YACVI,OAAO,CAACe,KAAK,CAAC,2BAA2B,EAAEnB,GAAG,CAAC;YAC/C0f,OAAI,CAAC5Z,kBAAkB,GAAG,KAAK;YAC/B4Z,OAAI,CAACC,wBAAwB,CAAC,CAAC;UACnC,CAAC,CAAC;QACV,CAAC;QACDH,oBAAoB,WAApBA,oBAAoBA,CAAA,EAAG;UACnB,IAAI,CAAC,IAAI,CAAC1Z,kBAAkB,EAAE;YAC1B;UACJ;UAEA,IAAI,CAACA,kBAAkB,GAAG,KAAK;UAC/B,IAAI,CAAC6Z,wBAAwB,CAAC,CAAC;;UAE/B;UACA,IAAI,IAAI,CAAC9N,UAAU,EAAE;YACjB,IAAI,CAACA,UAAU,CAACkM,MAAM,CAAC,kBAAkB,CAAC,SAAM,CAAC,YAAY,CAAE,CAAC,CAAC;UACrE;UAEA,IAAI,IAAI,CAACtZ,WAAW,IAAI,IAAI,CAACC,aAAa,EAAE;YACxC,IAAI,CAACA,aAAa,CAAC2V,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC5V,WAAW,GAAG,KAAK;UAC5B;UAEA,IAAI,CAACyP,SAAS,CAAC,CAAC;UAChB,IAAI,CAACX,8BAA8B,GAAG,EAAE;UACxC,IAAI,CAACG,2BAA2B,GAAG,IAAI;;UAEvC;UACA,IAAI,IAAI,CAACuM,qBAAqB,EAAE;YAC5B,IAAI,CAACA,qBAAqB,CAACgB,KAAK,CAAC,CAAC,SAAM,CAAC,YAAY,CAAE,CAAC,CAAC;YACzD,IAAI,CAAChB,qBAAqB,GAAG,IAAI;YACjC,IAAI,CAACC,qBAAqB,GAAG,IAAI;UACrC;;UAEA;UACA,IAAI,IAAI,CAAC/L,6BAA6B,EAAE;YACpC,IAAI3B,GAAG,GAAG,IAAI,CAACzO,QAAQ,CAAC,IAAI,CAACoQ,6BAA6B,CAACzY,KAAK,CAAC;YACjE,IAAI8W,GAAG,EAAE;cACLA,GAAG,CAAC7O,WAAW,GAAG,KAAK;YAC3B;YACA,IAAI,CAACwQ,6BAA6B,GAAG,IAAI;UAC7C;;UAEA;UACA,KAAK,IAAI/gB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG,IAAI,CAAC2Q,QAAQ,CAAC3P,MAAM,EAAEhB,CAAC,EAAE,EAAE;YAC3C,IAAI,IAAI,CAAC2Q,QAAQ,CAAC3Q,CAAC,CAAC,CAACuQ,WAAW,EAAE;cAC9B,IAAI,CAACI,QAAQ,CAAC3Q,CAAC,CAAC,CAACuQ,WAAW,GAAG,KAAK;YACxC;UACJ;;UAEA;UACA,IAAI,CAACsR,mBAAmB,CAAC;YACrBtW,IAAI,EAAE,oBAAoB;YAC1B+C,OAAO,EAAE,qBAAqB;YAC9BqP,IAAI,EAAE,0BAA0B;YAChCmQ,WAAW,EAAE,IAAI;YACjBC,aAAa,EAAE;UACnB,CAAC,CAAC;QACN,CAAC;QACDxB,wBAAwB,WAAxBA,wBAAwBA,CAAA,EAAG;UACvB,IAAI,CAAC,IAAI,CAAC9Z,kBAAkB,EAAE;YAC1B;UACJ;UAEA,IAAI,IAAI,CAACC,kBAAkB,EAAE;YACzB,IAAI,CAACD,kBAAkB,CAACoD,SAAS,CAACC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC;YAC9D,IAAI,CAACrD,kBAAkB,CAACoD,SAAS,CAACyB,MAAM,CAAC,UAAU,EAAE,kBAAkB,EAAE,uBAAuB,CAAC;YACjG,IAAI,CAAC7E,kBAAkB,CAAC6K,KAAK,GAAG,IAAI,CAAC7K,kBAAkB,CAACsK,YAAY,CAAC,gBAAgB,CAAC,IAAI,kBAAkB;YAC5G,IAAIiR,OAAO,GAAG,IAAI,CAACvb,kBAAkB,CAACsK,YAAY,CAAC,eAAe,CAAC;YACnE,IAAIiR,OAAO,EAAE;cACT,IAAI,CAACvb,kBAAkB,CAAC+J,eAAe,CAAChO,SAAS,CAACC,QAAQ,CAACuf,OAAO,EAAE;gBAAEvR,mBAAmB,EAAE;cAAK,CAAC,CAAC,CAAC;YACvG;UACJ,CAAC,MAAM;YACH,IAAI,CAAChK,kBAAkB,CAACoD,SAAS,CAACyB,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;YACjE,IAAI,CAAC7E,kBAAkB,CAACoD,SAAS,CAACyB,MAAM,CAAC,UAAU,EAAE,uBAAuB,CAAC;YAC7E,IAAI,CAAC7E,kBAAkB,CAACoD,SAAS,CAACC,GAAG,CAAC,kBAAkB,CAAC;YACzD,IAAI,CAACrD,kBAAkB,CAACwb,IAAI,CAAC,CAAC;YAC9B,IAAI,CAACxb,kBAAkB,CAAC6K,KAAK,GAAG,IAAI,CAAC7K,kBAAkB,CAACsK,YAAY,CAAC,kBAAkB,CAAC,IAAI,oBAAoB;YAChH,IAAImR,SAAS,GAAG,IAAI,CAACzb,kBAAkB,CAACsK,YAAY,CAAC,iBAAiB,CAAC;YACvE,IAAImR,SAAS,EAAE;cACX,IAAI,CAACzb,kBAAkB,CAAC+J,eAAe,CAAChO,SAAS,CAACC,QAAQ,CAACyf,SAAS,EAAE;gBAAEzR,mBAAmB,EAAE;cAAK,CAAC,CAAC,CAAC;YACzG;UACJ;QACJ,CAAC;QACD0R,0BAA0B,WAA1BA,0BAA0BA,CAAA,EAAG;UACzB;QAAA,CACH;QACDnC,4BAA4B,WAA5BA,4BAA4BA,CAAA,EAAG;UAC3B;UACA;UACA;QAAA,CACH;QACDoC,cAAc,WAAdA,cAAcA,CAACta,OAAO,EAAE;UACpB,IAAI,CAACA,OAAO,EAAE;YACV9G,OAAO,CAACe,KAAK,CAAC,mCAAmC,CAAC;YAElD;UACJ;UAEA,IAAIsgB,iBAAiB,GAAGva,OAAO,CAACiJ,YAAY,CAAC,iBAAiB,CAAC;UAC/D,IAAIrD,SAAS,GAAG,IAAI,CAACW,YAAY,CAAC,CAAC;UACnC,IAAIkN,gBAAgB,GAAG,IAAI,CAACjN,YAAY,CAAC,CAAC;UAE1C,IAAI,CAAC+T,iBAAiB,IAAI,CAAC3U,SAAS,EAAE;YAElC1M,OAAO,CAACe,KAAK,CAAC,kFAAkF,CAAC;YACjG;UACJ;;UAEA;UACA,IAAI,CAACmX,aAAa,CAACmJ,iBAAiB,EAAE,IAAI,EAAE9G,gBAAgB,CAAC;QACjE,CAAC;QACD+G,gBAAgB,WAAhBA,gBAAgBA,CAACC,OAAO,EAAEC,KAAK,EAAEntB,KAAK,EAAE;UAEpC,IAAMotB,OAAO,GAAGF,OAAO,CAACG,WAAW,CAAC,CAAC,CAACrR,UAAU,CAAC,MAAM,CAAC,GAAGkR,OAAO,GAAGhqB,MAAM,CAACoqB,QAAQ,CAACC,MAAM,GAAGL,OAAO;UACrG,IAAM9nB,GAAG,GAAG,IAAI+kB,GAAG,CAACiD,OAAO,CAAC;UAE5BhoB,GAAG,CAACooB,YAAY,CAACzD,GAAG,CAACoD,KAAK,EAAEntB,KAAK,CAAC;UAElC,OAAOoF,GAAG,CAACzC,QAAQ,CAAC,CAAC;QACzB,CAAC;QACD2jB,mBAAmB,WAAnBA,mBAAmBA,CAAA,EAAG;UAClB,IAAI,CAACtI,UAAU,CAAC;YACZvM,IAAI,EAAE,WAAW;YACjB0N,WAAW,EAAE3U,MAAM,CAACtF;UACxB,CAAC,CAAC;QACN,CAAC;QACD2a,mBAAmB,WAAnBA,mBAAmBA,CAAA,EAAG;UAClB,IAAM4N,cAAc,GAAG,IAAI,CAACne,QAAQ,CAAC3P,MAAM;UAC3C,IAAI,CAAC2P,QAAQ,GAAG,IAAI,CAACA,QAAQ,CAACmS,MAAM,CAAC,UAAA1D,GAAG;YAAA,OAAIA,GAAG,CAACtM,IAAI,KAAK,WAAW;UAAA,EAAC;UACrE,IAAMic,YAAY,GAAGD,cAAc,GAAG,IAAI,CAACne,QAAQ,CAAC3P,MAAM;UAC1D,OAAO+tB,YAAY;QACvB,CAAC;QACDlN,mBAAmB,WAAnBA,mBAAmBA,CAACD,YAAY,EAAE;UAAA,IAAAoN,OAAA;UAC9B,IAAI,CAACpN,YAAY,IAAI,CAACA,YAAY,CAACrW,IAAI,EAAE;YACrC;UACJ;UACA,IAAI,CAAC0jB,wBAAwB,CAACrN,YAAY,CAACrW,IAAI,CAAC;UAChD,IAAI2jB,aAAa,GAAG,IAAI,CAACte,aAAa,CAACue,SAAS,CAAC,UAAAvvB,CAAC;YAAA,OAAIA,CAAC,CAAC2L,IAAI,KAAKqW,YAAY,CAACrW,IAAI;UAAA,EAAC;UACnF,IAAI2jB,aAAa,IAAI,CAAC,EAAE;YACpB,IAAI,CAACte,aAAa,CAACkL,MAAM,CAACoT,aAAa,EAAE,CAAC,EAAEtN,YAAY,CAAC;UAC7D,CAAC,MAAM;YACH,IAAI,CAAChR,aAAa,CAACvM,IAAI,CAACud,YAAY,CAAC;UACzC;UACA,IAAI,CAACwN,2BAA2B,CAACxN,YAAY,CAAC;UAC9C,IAAI,CAACtC,SAAS,CAAC,YAAM;YACjB0P,OAAI,CAACtO,cAAc,CAAC,CAAC;UACzB,CAAC,CAAC;QACN,CAAC;QACDoB,kBAAkB,WAAlBA,kBAAkBA,CAACF,YAAY,EAAE;UAC7B,IAAI,CAACA,YAAY,IAAI,CAACA,YAAY,CAACrW,IAAI,EAAE;YACrC;UACJ;UACA,IAAI,CAAC0jB,wBAAwB,CAACrN,YAAY,CAACrW,IAAI,CAAC;UAChD,IAAI2jB,aAAa,GAAG,IAAI,CAACte,aAAa,CAACue,SAAS,CAAC,UAAAvvB,CAAC;YAAA,OAAIA,CAAC,CAAC2L,IAAI,KAAKqW,YAAY,CAACrW,IAAI;UAAA,EAAC;UACnF,IAAI2jB,aAAa,IAAI,CAAC,EAAE;YACpB,IAAI,CAACte,aAAa,CAACkL,MAAM,CAACoT,aAAa,EAAE,CAAC,EAAEtN,YAAY,CAAC;YACzD,IAAI,CAACwN,2BAA2B,CAACxN,YAAY,CAAC;UAClD;QACJ,CAAC;QACDwN,2BAA2B,WAA3BA,2BAA2BA,CAACxN,YAAY,EAAE;UAAA,IAAAyN,OAAA;UACtC,IAAI,CAACzN,YAAY,IAAI,CAACA,YAAY,CAACrW,IAAI,IAAI,CAACqW,YAAY,CAACmM,aAAa,IAAInM,YAAY,CAACmM,aAAa,IAAI,CAAC,EAAE;YACvG;UACJ;UACA,IAAI,CAACpb,yBAAyB,CAACiP,YAAY,CAACrW,IAAI,CAAC,GAAGkM,UAAU,CAAC,YAAM;YACjE4X,OAAI,CAACrN,kBAAkB,CAACJ,YAAY,CAACrW,IAAI,CAAC;UAC9C,CAAC,EAAEqW,YAAY,CAACmM,aAAa,CAAC;QAClC,CAAC;QACDkB,wBAAwB,WAAxBA,wBAAwBA,CAAClN,gBAAgB,EAAE;UACvC,IAAIuN,OAAO,GAAG,IAAI,CAAC3c,yBAAyB,CAACoP,gBAAgB,CAAC;UAC9D,IAAI,CAACuN,OAAO,EAAE;YACV;UACJ;UACAC,YAAY,CAACD,OAAO,CAAC;UACrB,OAAO,IAAI,CAAC3c,yBAAyB,CAACoP,gBAAgB,CAAC;QAC3D,CAAC;QACDC,kBAAkB,WAAlBA,kBAAkBA,CAACD,gBAAgB,EAAE;UACjC,IAAI,CAACkN,wBAAwB,CAAClN,gBAAgB,CAAC;UAC/C,IAAI,CAACnR,aAAa,GAAG,IAAI,CAACA,aAAa,CAACkS,MAAM,CAAC,UAAAljB,CAAC;YAAA,OAAIA,CAAC,CAAC2L,IAAI,KAAKwW,gBAAgB;UAAA,EAAC;QACpF,CAAC;QACDyN,mBAAmB,WAAnBA,mBAAmBA,CAACzN,gBAAgB,EAAE;UAClC,IAAI,CAACC,kBAAkB,CAACD,gBAAgB,CAAC;QAC7C,CAAC;QACD0N,wBAAwB,WAAxBA,wBAAwBA,CAAC1N,gBAAgB,EAAE2N,UAAU,EAAE;UACnD,IAAI,CAAC,IAAI,CAACjR,UAAU,EAAE;YAClB;UACJ;UACA,IAAI/E,SAAS,GAAG,IAAI,CAACW,YAAY,CAAC,CAAC;UACnC,IAAI,CAACoE,UAAU,CAACkM,MAAM,CAAC,0BAA0B,EAAEjR,SAAS,EAAEqI,gBAAgB,EAAE2N,UAAU,CAAC,SAAM,CAAC,UAAU9iB,GAAG,EAAE;YAC7GI,OAAO,CAACe,KAAK,CAAC,qCAAqC,EAAEnB,GAAG,CAAC;UAC7D,CAAC,CAAC;QACN,CAAC;QACD8T,cAAc,WAAdA,cAAcA,CAAA,EAAG;UAAA,IAAAiP,OAAA;UACb,IAAI,CAAC,IAAI,CAAClf,UAAU,EAAE;YAClB;UACJ;UACAgH,UAAU,CAAC,YAAM;YACbkY,OAAI,CAAClgB,aAAa,CAACmgB,SAAS,GAAGD,OAAI,CAAClgB,aAAa,CAACogB,YAAY,GAAGF,OAAI,CAAClgB,aAAa,CAACqgB,YAAY;UACpG,CAAC,EAAE,EAAE,CAAC;QACV,CAAC;QACDC,eAAe,WAAfA,eAAeA,CAAC7Y,KAAK,EAAE;UACnB,IAAI,CAACrG,MAAM,GAAGqG,KAAK,CAACgB,MAAM,CAAC7W,KAAK;QACpC,CAAC;QACDiZ,YAAY,WAAZA,YAAYA,CAAA,EAAG;UACX,OAAO,IAAI,CAAC/K,YAAY,CAACwN,YAAY,CAAC,iBAAiB,CAAC;QAC5D,CAAC;QACDiT,YAAY,WAAZA,YAAYA,CAACtW,SAAS,EAAE;UACpB,IAAI,CAACnK,YAAY,CAACya,YAAY,CAAC,iBAAiB,EAAEtQ,SAAS,IAAI,EAAE,CAAC;QACtE,CAAC;QACDuW,YAAY,WAAZA,YAAYA,CAAA,EAAG;UACX,IAAI,CAACvQ,aAAa,CAAC,CAAC;UACpB,IAAI,CAACsQ,YAAY,CAAC,EAAE,CAAC;UACrB,IAAI,CAACrgB,gBAAgB,GAAG,KAAK;UAC7B,IAAI,CAACugB,aAAa,GAAG,IAAI;UACzB,IAAI,IAAI,CAAC5f,mBAAmB,EAAE;YAC1B6C,YAAY,CAACyM,UAAU,CAAC,IAAI,CAAC/P,sBAAsB,CAAC;UACxD;UACA,IAAI,CAACc,QAAQ,GAAG,EAAE;UAClB,IAAI,CAACG,SAAS,GAAG,EAAE;UACnB,IAAI,CAACjF,MAAM,CAACwW,iBAAiB,EAAE;YAC3B,IAAI,CAACkC,eAAe,CAAC,CAAC;UAC1B;UAEA,IAAI1Y,MAAM,CAACwW,iBAAiB,EAAE;YAC1B,IAAI,CAACxC,eAAe,CAAC,CAAC;UAC1B;QACJ,CAAC;QACDA,eAAe,WAAfA,eAAeA,CAAA,EAAG;UACd,IAAI,CAAC,IAAI,CAAC4E,6BAA6B,CAAC,CAAC,EAAE;YACvC;UACJ;UAEA,IAAM9K,SAAS,GAAG,IAAI,CAACW,YAAY,CAAC,CAAC;UACrC,IAAI,CAACX,SAAS,IAAI,CAAC,IAAI,CAAC8E,UAAU,EAAE;YAChC;UACJ;UAEA,IAAI,CAACA,UAAU,CAACkM,MAAM,CAAC,cAAc,EAAEhR,SAAS,EAAE,IAAI,CAAC,SAAM,CAAC,UAAA/M,GAAG;YAAA,OAAII,OAAO,CAACe,KAAK,CAACnB,GAAG,CAAC;UAAA,EAAC;QAC5F,CAAC;QACDujB,aAAa,WAAbA,aAAaA,CAAA,EAAG;UAAA,IAAAC,OAAA;UACZ,IAAI,CAAC7gB,YAAY,GAAGxI,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACqD,oBAAoB,CAAC;UACvE,IAAI,CAACM,aAAa,GAAGzI,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACsD,yBAAyB,CAAC;UAC7E,IAAI,CAACM,aAAa,GAAG1I,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACoD,4BAA4B,CAAC;UAChF,IAAI,CAACS,WAAW,GAAG3I,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACwkB,0BAA0B,CAAC;UAC5E,IAAI,CAAC5L,6BAA6B,CAAC,CAAC;UAEpC,IAAM/K,SAAS,GAAG,IAAI,CAACW,YAAY,CAAC,CAAC;UACrC,IAAI,CAACvL,eAAe,IAAI4K,SAAS,EAAE;YAC/B,IAAI,CAAC4W,WAAW,CAAC5W,SAAS,CAAC;UAC/B,CAAC,MAAM,IAAI,IAAI,CAAC8K,uBAAuB,CAAC,CAAC,IAAI3Y,MAAM,CAACwW,iBAAiB,IAAI,CAACvT,eAAe,IAAI,CAAC4K,SAAS,EAAE;YACrG,IAAI,CAACmG,eAAe,CAAC,CAAC;UAC1B;;UAEA;UACA,IAAIhU,MAAM,CAAC+M,uBAAuB,IAAI/M,MAAM,CAAC0kB,mBAAmB,EAAE;YAC9D,IAAI,CAACpf,WAAW,GAAGpK,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAAC0kB,mBAAmB,CAAC;YACrE,IAAI,IAAI,CAACpf,WAAW,EAAE;cAClB,IAAI,CAACoJ,iBAAiB,CAAC,CAAC;;cAExB;cACA,IAAIlB,SAAS,GAAGtS,QAAQ,CAACC,aAAa,CAAC,OAAO,CAAC;cAC/CqS,SAAS,CAAC9N,IAAI,GAAG,MAAM;cACvB8N,SAAS,CAAC4G,EAAE,GAAG,mBAAmB;cAClC5G,SAAS,CAACmX,SAAS,GAAG,QAAQ;cAC9BnX,SAAS,CAACoX,QAAQ,GAAG,IAAI;cACzB,IAAI5kB,MAAM,CAAC6kB,iBAAiB,EAAE;gBAC1BrX,SAAS,CAACsX,MAAM,GAAG9kB,MAAM,CAAC6kB,iBAAiB;cAC/C;cACArX,SAAS,CAACrB,gBAAgB,CAAC,QAAQ,EAAE,UAACxY,CAAC;gBAAA,OAAK4wB,OAAI,CAAC7W,qBAAqB,CAAC/Z,CAAC,CAAC;cAAA,EAAC;cAC1E,IAAI,CAAC2R,WAAW,CAACyf,aAAa,CAACC,WAAW,CAACxX,SAAS,CAAC;;cAErD;cACA,IAAIP,SAAS,GAAG,IAAI,CAACvJ,YAAY,GAAG,IAAI,CAACA,YAAY,CAAC4I,OAAO,CAAC,wCAAwC,CAAC,GAAG,IAAI;cAC9G,IAAIW,SAAS,EAAE;gBACXA,SAAS,CAACd,gBAAgB,CAAC,UAAU,EAAE,UAACxY,CAAC;kBAAA,OAAK4wB,OAAI,CAACzX,cAAc,CAACnZ,CAAC,CAAC;gBAAA,EAAC;gBACrEsZ,SAAS,CAACd,gBAAgB,CAAC,WAAW,EAAE,UAACxY,CAAC;kBAAA,OAAK4wB,OAAI,CAACrX,eAAe,CAACvZ,CAAC,CAAC;gBAAA,EAAC;gBACvEsZ,SAAS,CAACd,gBAAgB,CAAC,MAAM,EAAE,UAACxY,CAAC;kBAAA,OAAK4wB,OAAI,CAACpX,UAAU,CAACxZ,CAAC,CAAC;gBAAA,EAAC;cACjE;YACJ;UACJ;;UAEA;UACA,IAAI,CAACiQ,aAAa,CAACuI,gBAAgB,CAAC,QAAQ,EAAE,YAAM;YAChD,IAAI,CAACoY,OAAI,CAAC1f,MAAM,EAAE;cACd;YACJ;YACA,IAAMogB,SAAS,GAAG,EAAE;YACpB,IAAMC,QAAQ,GAAGX,OAAI,CAAC3gB,aAAa,CAACogB,YAAY,GAAGO,OAAI,CAAC3gB,aAAa,CAACqgB,YAAY,GAAGM,OAAI,CAAC3gB,aAAa,CAACmgB,SAAS,IAAIkB,SAAS;YAC9HV,OAAI,CAAC3f,UAAU,GAAGsgB,QAAQ;UAC9B,CAAC,CAAC;UAEF,IAAI,CAACxhB,YAAY,CAACyI,gBAAgB,CAAC,SAAS,EAAE,UAAAd,KAAK,EAAI;YAEnD,IAAIkZ,OAAI,CAAC1f,MAAM,IAAI,IAAI,EAAE;cACrB;YACJ;YAEA,IAAIwG,KAAK,CAAChO,GAAG,KAAK,OAAO,IAAI,CAACgO,KAAK,CAAC8Z,QAAQ,EAAE;cAC1C9Z,KAAK,CAACmB,cAAc,CAAC,CAAC;cACtB+X,OAAI,CAAC5gB,aAAa,CAAC8J,KAAK,CAAC,CAAC;YAC9B;UACJ,CAAC,CAAC;UAEF,IAAI,CAAC/J,YAAY,CAACyI,gBAAgB,CAAC,OAAO,EAAE,UAACxY,CAAC,EAAK;YAC/C4wB,OAAI,CAACL,eAAe,CAACvwB,CAAC,CAAC;YAEvB,IAAIA,CAAC,CAAC0Y,MAAM,CAAC7W,KAAK,CAACsF,IAAI,CAAC,CAAC,EAAE;cACvBypB,OAAI,CAAC5gB,aAAa,CAAC0a,eAAe,CAAC,UAAU,CAAC;YAClD,CAAC,MAAM;cACHkG,OAAI,CAAC5gB,aAAa,CAACwa,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;YACrD;UACJ,CAAC,CAAC;UAEF,IAAI,CAACxa,aAAa,CAACwI,gBAAgB,CAAC,OAAO,EAAE,YAAM;YAE/C,IAAIoY,OAAI,CAAC1f,MAAM,IAAI,IAAI,EAAE;cACrB0f,OAAI,CAAC1f,MAAM,CAAC+W,OAAO,CAAC,CAAC;cACrB2I,OAAI,CAAC1f,MAAM,GAAG,IAAI;cAElB0f,OAAI,CAAC1H,iBAAiB,CAAC,CAAC;cACxB0H,OAAI,CAAClP,mBAAmB,CAAC,CAAC;;cAE1B;cACA,IAAIkP,OAAI,CAACzf,QAAQ,CAAC3P,MAAM,GAAG,CAAC,EAAE;gBAC1B,IAAMiwB,OAAO,GAAGb,OAAI,CAACzf,QAAQ,CAACyf,OAAI,CAACzf,QAAQ,CAAC3P,MAAM,GAAG,CAAC,CAAC;gBACvD,IAAIiwB,OAAO,CAACne,IAAI,KAAK,WAAW,IAAI,CAACme,OAAO,CAAC3iB,OAAO,EAAE;kBAClD8hB,OAAI,CAACzf,QAAQ,CAACugB,GAAG,CAAC,CAAC;gBACvB,CAAC,MAAM,IAAID,OAAO,CAAC1gB,WAAW,EAAE;kBAC5B0gB,OAAO,CAAC1gB,WAAW,GAAG,KAAK;gBAC/B;cACJ;cAEA;YACJ;YAEA6f,OAAI,CAAC3Q,WAAW,CAAC,CAAC;UACtB,CAAC,CAAC;UAEF,IAAM0R,gBAAgB,GAAGpqB,QAAQ,CAACqqB,sBAAsB,CAAC,0BAA0B,CAAC;UAEpF,KAAK,IAAIpxB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGmxB,gBAAgB,CAACnwB,MAAM,EAAEhB,CAAC,EAAE,EAAE;YAC9CmxB,gBAAgB,CAACnxB,CAAC,CAAC,CAACgY,gBAAgB,CAAC,OAAO,EAAE,UAACxY,CAAC,EAAK;cACjDA,CAAC,CAAC6Y,cAAc,CAAC,CAAC;cAClB+X,OAAI,CAAChC,cAAc,CAAC5uB,CAAC,CAAC0Y,MAAM,CAAC;YACjC,CAAC,CAAC;UACN;UAEA,IAAMmZ,YAAY,GAAGtqB,QAAQ,CAACqqB,sBAAsB,CAAC,2BAA2B,CAAC;UAEjF,KAAK,IAAIpxB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGqxB,YAAY,CAACrwB,MAAM,EAAEhB,CAAC,EAAE,EAAE;YAC1CqxB,YAAY,CAACrxB,CAAC,CAAC,CAACgY,gBAAgB,CAAC,OAAO,EAAE,UAACxY,CAAC,EAAK;cAC7CA,CAAC,CAAC6Y,cAAc,CAAC,CAAC;cAElB,IAAIqB,SAAS,GAAGla,CAAC,CAAC0Y,MAAM,CAAC6E,YAAY,CAAC,iBAAiB,CAAC;cAExD,IAAI,CAACrD,SAAS,EAAE;gBACZ1M,OAAO,CAACe,KAAK,CAAC,kFAAkF,CAAC;gBAEjG;cACJ;cAEAqiB,OAAI,CAACE,WAAW,CAAC5W,SAAS,CAAC;cAC3B0W,OAAI,CAACkB,cAAc,CAAC,CAAC;YACzB,CAAC,CAAC;UACN;UAEA,KAAK,IAAItxB,GAAC,GAAG,CAAC,EAAEA,GAAC,GAAG6L,MAAM,CAAC8E,QAAQ,CAAC3P,MAAM,EAAEhB,GAAC,EAAE,EAAE;YAC7C,IAAI,CAACqf,UAAU,CAACxT,MAAM,CAAC8E,QAAQ,CAAC3Q,GAAC,CAAC,CAAC;UACvC;;UAEA;UACA,IAAI,CAACsf,SAAS,CAAC,YAAM;YACjB8Q,OAAI,CAAC7Q,uBAAuB,CAAC,CAAC;UAClC,CAAC,CAAC;;UAEF;UACA,IAAI,IAAI,CAAC9P,aAAa,EAAE;YACpB,IAAI,CAACA,aAAa,CAACuI,gBAAgB,CAAC,OAAO,EAAE,UAACxY,CAAC,EAAK;cAChD,IAAI+xB,GAAG,GAAG/xB,CAAC,CAAC0Y,MAAM,CAACC,OAAO,CAAC,mBAAmB,CAAC;cAC/C,IAAI,CAACoZ,GAAG,EAAE;gBACN;cACJ;cAEA,IAAIC,KAAK,GAAGD,GAAG,CAACpZ,OAAO,CAAC,gBAAgB,CAAC,IAAIoZ,GAAG,CAACpZ,OAAO,CAAC,KAAK,CAAC;cAC/D,IAAI,CAACqZ,KAAK,EAAE;gBACR;cACJ;cAEA,IAAIC,MAAM,GAAGD,KAAK,CAACtU,aAAa,CAAC,MAAM,CAAC;cACxC,IAAIuU,MAAM,EAAE;gBACRpM,SAAS,CAACqM,SAAS,CAACC,SAAS,CAACF,MAAM,CAACxqB,WAAW,CAAC;gBACjD,IAAI2qB,UAAU,GAAG/lB,MAAM,CAACzG,cAAc,IAAI,SAAS;gBACnDmsB,GAAG,CAACrqB,SAAS,GAAG,oCAAoC,GAAG0qB,UAAU;gBACjEna,UAAU,CAAC,YAAM;kBACb8Z,GAAG,CAACrqB,SAAS,GAAG,oCAAoC;gBACxD,CAAC,EAAE,IAAI,CAAC;cACZ;YACJ,CAAC,CAAC;UACN;;UAEA;UACA,IAAI,IAAI,CAACuK,mBAAmB,IAAI5F,MAAM,CAACgmB,wBAAwB,EAAE;YAC7D,IAAI,CAACrgB,SAAS,GAAGzK,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACgmB,wBAAwB,CAAC;YACxE,IAAI,IAAI,CAACrgB,SAAS,EAAE;cAChB,IAAI,CAACA,SAAS,CAACwD,KAAK,CAAC8P,OAAO,GAAG,EAAE;cACjC,IAAI,CAACtT,SAAS,CAACwG,gBAAgB,CAAC,OAAO,EAAE,YAAM;gBAC3CoY,OAAI,CAAC9I,eAAe,CAAC,CAAC;cAC1B,CAAC,CAAC;YACN;UACJ;;UAEA;UACA,IAAI,IAAI,CAAC9U,uBAAuB,IAAI3G,MAAM,CAACimB,iCAAiC,EAAE;YAC1E,IAAI,CAACrf,kBAAkB,GAAG1L,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACimB,iCAAiC,CAAC;YAC1F,IAAI,IAAI,CAACrf,kBAAkB,EAAE;cACzB,IAAI,CAACA,kBAAkB,CAACuF,gBAAgB,CAAC,OAAO,EAAE,YAAM;gBACpDoY,OAAI,CAACjE,sBAAsB,CAAC,CAAC;cACjC,CAAC,CAAC;YACN;UACJ;QACJ,CAAC;QACDmE,WAAW,WAAXA,WAAWA,CAAC5W,SAAS,EAAE;UACnB,IAAI,CAAC+E,UAAU,CAACkM,MAAM,CAAC,aAAa,EAAEjR,SAAS,CAAC,SAAM,CAAC,UAAA9M,GAAG;YAAA,OAAII,OAAO,CAACe,KAAK,CAACnB,GAAG,CAAC;UAAA,EAAC;QACrF,CAAC;QACDwV,oBAAoB,WAApBA,oBAAoBA,CAAA,EAAG;UAEnB,IAAI1I,SAAS,GAAG,IAAI,CAACW,YAAY,CAAC,CAAC;UACnC,IAAIX,SAAS,EAAE;YACX,IAAI,CAAC4W,WAAW,CAAC5W,SAAS,CAAC;UAC/B;QACJ,CAAC;QACDsB,iBAAiB,WAAjBA,iBAAiBA,CAACtB,SAAS,EAAEqY,KAAK,EAAE;UAChC,IAAI,IAAI,CAACpiB,gBAAgB,IAAI,CAACoiB,KAAK,EAAE;YACjC;UACJ;UACA,IAAI,CAACtP,SAAS,CAAC,IAAIC,WAAW,CAAC,+BAA+B,EAAE;YAAEnF,MAAM,EAAE;cAAE7D,SAAS,EAAEA;YAAU;UAAE,CAAC,CAAC,CAAC;UACtG,IAAI,CAACsW,YAAY,CAACtW,SAAS,CAAC;UAC5B,IAAI,CAAC/J,gBAAgB,GAAG,IAAI;UAE5B,IAAI,IAAI,CAACW,mBAAmB,EAAE;YAC1B6C,YAAY,CAACQ,OAAO,CAAC,IAAI,CAAC9D,sBAAsB,EAAE6J,SAAS,CAAC;UAChE;QACJ,CAAC;QACDsY,gBAAgB,WAAhBA,gBAAgBA,CAAA,EAAG;UAAA,IAAAC,OAAA;UAEf,IAAI,CAACpmB,MAAM,CAACxG,MAAM,CAACC,mBAAmB,EAAE;YACpC0H,OAAO,CAACe,KAAK,CAAC,6CAA6C,CAAC;YAC5D;UACJ;UAEA,IAAI,CAAClC,MAAM,CAACxG,MAAM,CAACE,mBAAmB,EAAE;YACpCyH,OAAO,CAACe,KAAK,CAAC,6CAA6C,CAAC;YAC5D;UACJ;UAEA,IAAMzI,mBAAmB,GAAGyB,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACxG,MAAM,CAACC,mBAAmB,CAAC;UAErF,IAAI,CAACA,mBAAmB,EAAE;YACtB;UACJ;UAEA,IAAIuG,MAAM,CAACxG,MAAM,CAACG,kBAAkB,EAAE;YAClC,IAAI,CAACA,kBAAkB,GAAGuB,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACxG,MAAM,CAACG,kBAAkB,CAAC;UACtF;UAEA,IAAI,CAACD,mBAAmB,GAAGsG,MAAM,CAACxG,MAAM,CAACE,mBAAmB;UAC5D,IAAI,CAACsK,sBAAsB,GAAGhE,MAAM,CAACxG,MAAM,CAACE,mBAAmB,GAAG,SAAS;UAC3E,IAAI,CAACuK,mBAAmB,GAAGjE,MAAM,CAACxG,MAAM,CAACE,mBAAmB,GAAG,QAAQ;UACvE,IAAI,CAACwK,sBAAsB,GAAGzK,mBAAmB;UACjD,IAAI,CAAC0K,yBAAyB,GAAGnE,MAAM,CAACxG,MAAM,CAACO,oBAAoB,GAC7DmB,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACxG,MAAM,CAACO,oBAAoB,CAAC,GAC1D,IAAI;UACV,IAAI,CAACqK,4BAA4B,GAAGpE,MAAM,CAACxG,MAAM,CAACQ,uBAAuB,GACnEkB,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACxG,MAAM,CAACQ,uBAAuB,CAAC,GAC7D,IAAI;UACV,IAAI,CAACuK,kBAAkB,GAAGjJ,eAAe,CAAC0E,MAAM,CAACxG,MAAM,CAACa,YAAY,CAAC,IACjEiB,eAAe,CAAC5C,MAAM,CAAC8P,gBAAgB,CAAC/O,mBAAmB,CAAC,CAAC2O,KAAK,CAAC,IACnE,GAAG;UACP,IAAI,CAAC5D,mBAAmB,GAAGlJ,eAAe,CAAC0E,MAAM,CAACxG,MAAM,CAACc,aAAa,CAAC,IACnEgB,eAAe,CAAC5C,MAAM,CAAC8P,gBAAgB,CAAC/O,mBAAmB,CAAC,CAAC4O,MAAM,CAAC,IACpE,GAAG;UACP,IAAI,CAAC5D,mBAAmB,GAAG,IAAI;UAE/B,IAAIzE,MAAM,CAACxG,MAAM,CAACW,cAAc,EAAE;YAC9BV,mBAAmB,CAACuQ,SAAS,CAACC,GAAG,CAAC,0BAA0B,CAAC;YAC7DxQ,mBAAmB,CAAC0P,KAAK,CAAC5O,QAAQ,GAAG,CAACe,eAAe,CAAC0E,MAAM,CAACxG,MAAM,CAACe,QAAQ,CAAC,IAAI,GAAG,IAAI,IAAI;YAC5Fd,mBAAmB,CAAC0P,KAAK,CAAC3O,SAAS,GAAG,CAACc,eAAe,CAAC0E,MAAM,CAACxG,MAAM,CAACgB,SAAS,CAAC,IAAI,GAAG,IAAI,IAAI;YAE9F,IAAI,OAAO6rB,cAAc,KAAK,WAAW,EAAE;cACvC,IAAI,CAAChiB,oBAAoB,GAAG,IAAIgiB,cAAc,CAAC,YAAM;gBACjDD,OAAI,CAACzc,sBAAsB,CAAC,CAAC;gBAC7Byc,OAAI,CAAC/b,iCAAiC,CAAC,CAAC;gBACxC+b,OAAI,CAACrc,qCAAqC,CAAC,CAAC;cAChD,CAAC,CAAC;cAEF,IAAI,CAAC1F,oBAAoB,CAACiiB,OAAO,CAAC7sB,mBAAmB,CAAC;YAC1D;UACJ;UAEA,IAAIQ,kBAAkB,GAAG+F,MAAM,CAACxG,MAAM,CAACS,kBAAkB,IAAI,wBAAwB;UACrF,IAAIssB,UAAU,GAAG9sB,mBAAmB,CAAC4X,aAAa,CAACpX,kBAAkB,CAAC;UAEtE,IAAI+F,MAAM,CAACxG,MAAM,CAACU,cAAc,IAAIqsB,UAAU,EAAE;YAC5CA,UAAU,CAACvc,SAAS,CAACC,GAAG,CAAC,4BAA4B,CAAC;YACtDxQ,mBAAmB,CAACuQ,SAAS,CAACC,GAAG,CAAC,0BAA0B,CAAC;YAC7D,IAAI,CAACM,4BAA4B,CAAC9Q,mBAAmB,EAAE8sB,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC;UACtF;UAEA,IAAIvmB,MAAM,CAACxG,MAAM,CAACU,cAAc,IAAI,IAAI,CAACiK,yBAAyB,EAAE;YAChE,IAAI,CAACA,yBAAyB,CAAC6F,SAAS,CAACC,GAAG,CAAC,0BAA0B,CAAC;YACxE,IAAI,CAACM,4BAA4B,CAAC,IAAI,CAACpG,yBAAyB,EAAE,IAAI,CAACA,yBAAyB,EAAE,QAAQ,EAAE,IAAI,CAAC;UACrH;UAEA,IAAI,IAAI,CAACC,4BAA4B,EAAE;YACnC,IAAI,CAACA,4BAA4B,CAAC+H,gBAAgB,CAAC,OAAO,EAAE,UAACd,KAAK,EAAK;cACnEA,KAAK,CAACmB,cAAc,CAAC,CAAC;cACtB4Z,OAAI,CAACjc,eAAe,CAAC,CAAC;YAC1B,CAAC,CAAC;UACN;UAEA,IAAI,CAACG,mBAAmB,CAAC,CAAC;UAE1B,IAAI,CAAC,IAAI,CAAChG,2BAA2B,EAAE;YACnC,IAAI,CAACA,2BAA2B,GAAG,YAAM;cACrC8hB,OAAI,CAAC/b,iCAAiC,CAAC,CAAC;cACxC+b,OAAI,CAACrc,qCAAqC,CAAC,CAAC;YAChD,CAAC;YAEDrR,MAAM,CAACyT,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC7H,2BAA2B,CAAC;UACvE;;UAEA;UACA,IAAI,CAACiS,oBAAoB,CAAC,CAAC;UAE3B,IAAIvW,MAAM,CAACwW,iBAAiB,IAAI,CAAC,IAAI,CAAChI,YAAY,CAAC,CAAC,EAAE;YAClD,IAAI,CAACwF,eAAe,CAAC,CAAC;UAC1B;UAEA,IAAIhU,MAAM,CAACxG,MAAM,CAACI,iBAAiB,IAAI,IAAI,CAACD,kBAAkB,EAAE;YAE5D,IAAMC,iBAAiB,GAAGsB,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACxG,MAAM,CAACI,iBAAiB,CAAC;YAEjF,IAAIA,iBAAiB,EAAE;cACnBA,iBAAiB,CAACuS,gBAAgB,CAAC,OAAO,EAAE,YAAM;gBAC9Cia,OAAI,CAACzsB,kBAAkB,CAACqQ,SAAS,CAACnC,MAAM,CAAC,MAAM,CAAC;cACpD,CAAC,CAAC;YACN;YAEA,IAAI7H,MAAM,CAACxG,MAAM,CAACK,kBAAkB,EAAE;cAClC,IAAIA,kBAAkB,GAAGqB,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACxG,MAAM,CAACK,kBAAkB,CAAC;cAEjF,IAAIA,kBAAkB,EAAE;gBACpBA,kBAAkB,CAACsS,gBAAgB,CAAC,OAAO,EAAE,YAAM;kBAC/Cia,OAAI,CAACX,cAAc,CAAC,CAAC;gBACzB,CAAC,CAAC;cACN;YACJ;UACJ;UAEA,IAAIzlB,MAAM,CAACxG,MAAM,CAACM,aAAa,EAAE;YAC7B,IAAMA,aAAa,GAAGoB,QAAQ,CAACmW,aAAa,CAACrR,MAAM,CAACxG,MAAM,CAACM,aAAa,CAAC;YAEzE,IAAIA,aAAa,EAAE;cACfA,aAAa,CAACqS,gBAAgB,CAAC,OAAO,EAAE,YAAM;gBAC1Cia,OAAI,CAAChC,YAAY,CAAC,CAAC;gBACnBgC,OAAI,CAACX,cAAc,CAAC,CAAC;cACzB,CAAC,CAAC;YACN;UACJ;QACJ,CAAC;QACDA,cAAc,WAAdA,cAAcA,CAAA,EAAG;UAEb,IAAI,CAAC,IAAI,CAAC9rB,kBAAkB,EAAE;YAC1B;UACJ;UAEA,IAAI,CAACA,kBAAkB,CAACqQ,SAAS,CAACyB,MAAM,CAAC,MAAM,CAAC;QACpD,CAAC;QACD+C,YAAY,WAAZA,YAAYA,CAAA,EAAG;UACX,IAAIX,SAAS,GAAG,IAAI,CAACnK,YAAY,CAACwN,YAAY,CAAC,iBAAiB,CAAC;UAEjE,IAAI,CAACrD,SAAS,IAAI,IAAI,CAACpJ,mBAAmB,EAAE;YACxCoJ,SAAS,GAAGvG,YAAY,CAACC,OAAO,CAAC,IAAI,CAACvD,sBAAsB,CAAC;UACjE;UAEA,OAAO6J,SAAS;QACpB,CAAC;QACD2Y,YAAY,WAAZA,YAAYA,CAAC/lB,OAAO,EAAE;UAClB+Y,SAAS,CAACqM,SAAS,CAACC,SAAS,CAACrlB,OAAO,CAAC;QAC1C,CAAC;QACDgmB,mBAAmB,WAAnBA,mBAAmBA,CAACC,SAAS,EAAExS,UAAU,EAAE;UACvC,IAAI,CAACwS,SAAS,EAAE;YACZ;UACJ;UAEA,IAAIC,KAAK,GAAGD,SAAS,CAACrV,aAAa,CAAC,cAAc,CAAC;UACnD,IAAIuV,OAAO,GAAGF,SAAS,CAACrV,aAAa,CAAC,gBAAgB,CAAC;;UAEvD;UACA;UACA,IAAIsV,KAAK,EAAE;YACP,IAAIE,OAAO,GAAG3S,UAAU,KAAK,IAAI,GAAG,uBAAuB,GAAG,yBAAyB;YACvF,IAAI4S,MAAM,GAAG5rB,QAAQ,CAACC,aAAa,CAAC,GAAG,CAAC;YACxC2rB,MAAM,CAACnC,SAAS,GAAGkC,OAAO;YAC1BC,MAAM,CAAC3d,KAAK,CAAC4d,QAAQ,GAAG,QAAQ;YAChCJ,KAAK,CAACvrB,WAAW,GAAG,EAAE;YACtBurB,KAAK,CAAC3B,WAAW,CAAC8B,MAAM,CAAC;UAC7B;UAEA,IAAIF,OAAO,EAAE;YACT,IAAII,SAAS,GAAG9S,UAAU,KAAK,KAAK,GAAG,yBAAyB,GAAG,2BAA2B;YAC9F,IAAI+S,QAAQ,GAAG/rB,QAAQ,CAACC,aAAa,CAAC,GAAG,CAAC;YAC1C8rB,QAAQ,CAACtC,SAAS,GAAGqC,SAAS;YAC9BC,QAAQ,CAAC9d,KAAK,CAAC4d,QAAQ,GAAG,QAAQ;YAClCH,OAAO,CAACxrB,WAAW,GAAG,EAAE;YACxBwrB,OAAO,CAAC5B,WAAW,CAACiC,QAAQ,CAAC;UACjC;;UAEA;UACA,IAAIvuB,MAAM,CAACwuB,WAAW,IAAIA,WAAW,CAACC,GAAG,IAAID,WAAW,CAACC,GAAG,CAACC,KAAK,EAAE;YAChEF,WAAW,CAACC,GAAG,CAACC,KAAK,CAAC;cAAEC,IAAI,EAAEX;YAAU,CAAC,CAAC;UAC9C;QACJ,CAAC;QACDhT,uBAAuB,WAAvBA,uBAAuBA,CAAA,EAAG;UACtB,IAAI4T,UAAU,GAAG,IAAI,CAACC,GAAG,CAACxW,gBAAgB,CAAC,qCAAqC,CAAC;UAEjF,KAAK,IAAI5c,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGmzB,UAAU,CAACnyB,MAAM,EAAEhB,CAAC,EAAE,EAAE;YACxC,IAAIqzB,KAAK,GAAGF,UAAU,CAACnzB,CAAC,CAAC,CAAC+c,YAAY,CAAC,iBAAiB,CAAC;YACzD,IAAIqC,GAAG,GAAG,IAAI,CAACzO,QAAQ,CAACqP,IAAI,CAAC,UAAAle,CAAC;cAAA,OAAIA,CAAC,CAACme,EAAE,KAAKoT,KAAK;YAAA,EAAC;YAEjD,IAAIjU,GAAG,EAAE;cACL,IAAI,CAACkT,mBAAmB,CAACa,UAAU,CAACnzB,CAAC,CAAC,EAAEof,GAAG,CAACW,UAAU,CAAC;YAC3D;UACJ;QACJ,CAAC;QACDuT,WAAW,WAAXA,WAAWA,CAAChnB,OAAO,EAAEinB,UAAU,EAAErc,KAAK,EAAE;UACpC,IAAIwC,SAAS,GAAG,IAAI,CAACW,YAAY,CAAC,CAAC;UAEnC,IAAI,CAACX,SAAS,IAAI,CAACpN,OAAO,CAAC2T,EAAE,IAAI,CAAC,IAAI,CAACxB,UAAU,EAAE;YAC/C;UACJ;;UAEA;UACA,IAAI+U,SAAS,GAAGlnB,OAAO,CAACyT,UAAU,KAAKwT,UAAU,GAAG,IAAI,GAAGA,UAAU;UACrEjnB,OAAO,CAACyT,UAAU,GAAGyT,SAAS;;UAE9B;UACA,IAAIC,iBAAiB,GAAG,IAAI,CAACL,GAAG,CAAClW,aAAa,CAC1C,uDAAuD,GAAG5Q,OAAO,CAAC2T,EAAE,GAAG,IAC3E,CAAC;UAED,IAAI,CAACqS,mBAAmB,CAACmB,iBAAiB,EAAED,SAAS,CAAC;;UAEtD;UACA,IAAIA,SAAS,KAAK,IAAI,IAAIC,iBAAiB,EAAE;YACzChc,UAAU,CAAC,YAAM;cACb,IAAIic,QAAQ,GAAGH,UAAU,GAAG,cAAc,GAAG,gBAAgB;cAC7D,IAAIhC,GAAG,GAAGkC,iBAAiB,CAACvW,aAAa,CAACwW,QAAQ,CAAC;cAEnD,IAAInC,GAAG,EAAE;gBACLA,GAAG,CAAC1b,SAAS,CAACyB,MAAM,CAAC,cAAc,CAAC;gBACpC,KAAKia,GAAG,CAACoC,WAAW;gBACpBpC,GAAG,CAAC1b,SAAS,CAACC,GAAG,CAAC,cAAc,CAAC;gBACjCyb,GAAG,CAACvZ,gBAAgB,CAAC,cAAc,EAAE,SAAS4b,KAAKA,CAAA,EAAG;kBAClDrC,GAAG,CAACna,mBAAmB,CAAC,cAAc,EAAEwc,KAAK,CAAC;kBAC9CrC,GAAG,CAAC1b,SAAS,CAACyB,MAAM,CAAC,cAAc,CAAC;gBACxC,CAAC,CAAC;cACN;YACJ,CAAC,EAAE,EAAE,CAAC;UACV;UAEA,IAAI,CAACmH,UAAU,CAACkM,MAAM,CAAC,aAAa,EAAEjR,SAAS,EAAEpN,OAAO,CAAC2T,EAAE,EAAEsT,UAAU,CAAC,SAAM,CAAC,UAAU3mB,GAAG,EAAE;YAC1FI,OAAO,CAACe,KAAK,CAAC,yBAAyB,EAAEnB,GAAG,CAAC;UACjD,CAAC,CAAC;QACN;MACJ,CAAC;MACDinB,KAAK,EAAE;QACH/iB,SAAS,EAAE;UACPgjB,OAAO,WAAPA,OAAOA,CAAA,EAAG;YAAE,IAAI,CAACvZ,iBAAiB,CAAC,CAAC;UAAE,CAAC;UACvCwZ,IAAI,EAAE;QACV,CAAC;QACD/iB,WAAW,WAAXA,WAAWA,CAAA,EAAG;UAAE,IAAI,CAACuJ,iBAAiB,CAAC,CAAC;QAAE,CAAC;QAC3CxI,cAAc,WAAdA,cAAcA,CAAA,EAAG;UACb;UACA;QAAA,CACH;QACDW,kBAAkB,WAAlBA,kBAAkBA,CAACshB,MAAM,EAAE;UACvB;UACA,IAAI,IAAI,CAACxiB,SAAS,EAAE;YAChB,IAAI,CAACA,SAAS,CAACwD,KAAK,CAAC8P,OAAO,GAAGkP,MAAM,GAAG,MAAM,GAAI,IAAI,CAACviB,mBAAmB,GAAG,EAAE,GAAG,MAAO;UAC7F;;UAEA;UACA,IAAI,IAAI,CAACjC,aAAa,EAAE;YACpB,IAAI,CAACA,aAAa,CAACwF,KAAK,CAAC8P,OAAO,GAAGkP,MAAM,GAAG,MAAM,GAAG,EAAE;UAC3D;;UAEA;UACA,IAAI,IAAI,CAACzkB,YAAY,EAAE;YACnB,IAAI,CAACA,YAAY,CAACqV,QAAQ,GAAGoP,MAAM;YACnC,IAAIA,MAAM,EAAE;cACR,IAAI,CAACzkB,YAAY,CAACG,WAAW,GAAG,EAAE;YACtC;UACJ;QACJ;MACJ,CAAC;MACDukB,OAAO,WAAPA,OAAOA,CAAA,EAAG;QAAA,IAAAC,OAAA;QACNzxB,iBAAA,cAAAb,YAAA,GAAAE,CAAA,CAAC,SAAAqyB,SAAA;UAAA,OAAAvyB,YAAA,GAAAC,CAAA,WAAAuyB,SAAA;YAAA,kBAAAA,SAAA,CAAAx0B,CAAA;cAAA;gBAAAw0B,SAAA,CAAAx0B,CAAA;gBAAA,OACSs0B,OAAI,CAAC9V,eAAe,CAAC,CAAC;cAAA;gBAC5B8V,OAAI,CAAC/D,aAAa,CAAC,CAAC;gBACpB,IAAIrhB,eAAe,EAAE;kBACjBolB,OAAI,CAAClC,gBAAgB,CAAC,CAAC;gBAC3B;cAAC;gBAAA,OAAAoC,SAAA,CAAAvzB,CAAA;YAAA;UAAA,GAAAszB,QAAA;QAAA,CACJ,GAAE,CAAC;QAEJ5vB,MAAM,CAACyT,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAChF,kBAAkB,CAAC;QAChEzO,MAAM,CAACyT,gBAAgB,CAAC,4BAA4B,EAAE,IAAI,CAACqS,qBAAqB,CAAC;MACrF,CAAC;MACDgK,aAAa,WAAbA,aAAaA,CAAA,EAAG;QACZ9vB,MAAM,CAAC6S,mBAAmB,CAAC,cAAc,EAAE,IAAI,CAACpE,kBAAkB,CAAC;QACnEzO,MAAM,CAAC6S,mBAAmB,CAAC,4BAA4B,EAAE,IAAI,CAACiT,qBAAqB,CAAC;QAEpF,IAAI,CAACvJ,SAAS,CAAC,KAAK,CAAC;QAErB,IAAI,IAAI,CAACpQ,MAAM,EAAE;UACb,IAAI,CAACA,MAAM,CAAC+W,OAAO,CAAC,CAAC;UACrB,IAAI,CAAC/W,MAAM,GAAG,IAAI;QACtB;QACA,IAAI,IAAI,CAAC+N,UAAU,EAAE;UACjB,IAAI,CAACA,UAAU,CAACwI,IAAI,CAAC,CAAC;QAC1B;MACJ,CAAC;MACDqN,QAAQ,EAAEzoB,MAAM,CAACvF;IACrB,CAAC,CAAC,CAACiuB,KAAK,CAAC1oB,MAAM,CAACmD,kBAAkB,CAAC;IAEnC,OAAOI,GAAG;EACd,CAAC;EAED,OAAO;IACHR,UAAU,EAAEA;EAChB,CAAC;AACL,CAAC,CAAC,CAAC;;AAEH;AACA7H,QAAQ,CAACiR,gBAAgB,CAAC,OAAO,EAAE,UAAUxY,CAAC,EAAE;EAC5C,IAAM+xB,GAAG,GAAG/xB,CAAC,CAAC0Y,MAAM,CAACC,OAAO,CAAC,qBAAqB,CAAC;EACnD,IAAI,CAACoZ,GAAG,EAAE;IACN;EACJ;EACA,IAAM5mB,OAAO,GAAG4mB,GAAG,CAACxU,YAAY,CAAC,eAAe,CAAC;EACjD,IAAMlQ,MAAM,GAAGlC,OAAO,GAAG5D,QAAQ,CAAC+F,cAAc,CAACnC,OAAO,CAAC,GAAG,IAAI;EAChE,IAAI,CAACkC,MAAM,EAAE;IACTG,OAAO,CAACe,KAAK,CAAC,yBAAyB,EAAEpD,OAAO,CAAC;IACjD;EACJ;EACA,IAAMlC,IAAI,GAAG1B,QAAQ,CAACC,aAAa,CAAC,GAAG,CAAC;EACxCyB,IAAI,CAAC+rB,QAAQ,GAAG,QAAQ,GAAG7pB,OAAO,GAAG,MAAM;EAC3ClC,IAAI,CAACc,IAAI,GAAGsD,MAAM,CAAC4nB,SAAS,CAAC,WAAW,CAAC;EACzChsB,IAAI,CAAC6Q,KAAK,CAAC,CAAC;AAChB,CAAC,CAAC;;AAEF;AACAvS,QAAQ,CAACiR,gBAAgB,CAAC,OAAO,EAAE,UAAUxY,CAAC,EAAE;EAC5C,IAAMiJ,IAAI,GAAGjJ,CAAC,CAAC0Y,MAAM,CAACC,OAAO,CAAC,oBAAoB,CAAC;EACnD,IAAI,CAAC1P,IAAI,EAAE;IACP;EACJ;EAEA,IAAM8pB,SAAS,GAAG9pB,IAAI,CAAC0P,OAAO,CAAC,4BAA4B,CAAC;EAC5D,IAAMuc,GAAG,GAAGnC,SAAS,aAATA,SAAS,uBAATA,SAAS,CAAErV,aAAa,CAAC,KAAK,CAAC;EAC3C,IAAI,CAACwX,GAAG,EAAE;IACN;EACJ;EAEA,IAAMtqB,GAAG,GAAGsqB,GAAG,CAACtqB,GAAG;EACnB,IAAI,CAACA,GAAG,IAAI,CAACA,GAAG,CAACiT,UAAU,CAAC,OAAO,CAAC,EAAE;IAClC,OAAO,CAAC;EACZ;EAEA7d,CAAC,CAAC6Y,cAAc,CAAC,CAAC;EAElBqC,KAAK,CAACtQ,GAAG,CAAC,CACL5H,IAAI,CAAC,UAAUmyB,GAAG,EAAE;IAAE,OAAOA,GAAG,CAACtJ,IAAI,CAAC,CAAC;EAAE,CAAC,CAAC,CAC3C7oB,IAAI,CAAC,UAAU6oB,IAAI,EAAE;IAClB,IAAM5kB,GAAG,GAAG+kB,GAAG,CAACC,eAAe,CAACJ,IAAI,CAAC;IACrC,IAAMxqB,CAAC,GAAGkG,QAAQ,CAACC,aAAa,CAAC,GAAG,CAAC;IACrCnG,CAAC,CAAC0I,IAAI,GAAG9C,GAAG;IACZ5F,CAAC,CAAC2zB,QAAQ,GAAG/rB,IAAI,CAACsU,YAAY,CAAC,UAAU,CAAC,IAAI,qBAAqB;IACnEhW,QAAQ,CAAC6T,IAAI,CAACiW,WAAW,CAAChwB,CAAC,CAAC;IAC5BA,CAAC,CAACyY,KAAK,CAAC,CAAC;IACTvS,QAAQ,CAAC6T,IAAI,CAACga,WAAW,CAAC/zB,CAAC,CAAC;IAC5B4W,UAAU,CAAC,YAAY;MAAE+T,GAAG,CAACG,eAAe,CAACllB,GAAG,CAAC;IAAE,CAAC,EAAE,GAAG,CAAC;EAC9D,CAAC,CAAC,SACI,CAAC,UAAUmG,GAAG,EAAE;IAAEI,OAAO,CAACe,KAAK,CAAC,2BAA2B,EAAEnB,GAAG,CAAC;EAAE,CAAC,CAAC;AACnF,CAAC,CAAC","file":"ai-chat.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n
\n
\n
\n
{{ userLabel }}
\n
\n \n {{ getAssistantLabel(message) }}\n
\n
\n

{{ message.title }}

\n
\n \n \n \n \n \n
\n
\n
\n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n \n Assistant\n
\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.link = normalized.link ?? normalized.Link ?? null;\n\n return normalized;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `${data.text}`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `
${langDisplay}
${highlighted}
`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `
\n \"${alt}\"\n
\n \n \n \n
\n
`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `
`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., ).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});\n const hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isSessionStarted: false,\n isPlaceholderVisible: true,\n chatWidgetStateName: null,\n chatWidgetStateSession: null,\n chatWidgetLayoutKey: null,\n chatHistorySection: null,\n widgetContainerElement: null,\n widgetToggleButtonElement: null,\n widgetResetSizeButtonElement: null,\n widgetResizeObserver: null,\n widgetViewportResizeHandler: null,\n widgetDefaultWidth: null,\n widgetDefaultHeight: null,\n widgetIsInitialized: false,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n notifications: [],\n prompt: '',\n documents: config.existingDocuments || [],\n isUploading: false,\n uploadErrors: [],\n isDragOver: false,\n documentBar: null,\n metricsEnabled: !!config.metricsEnabled,\n userLabel: config.userLabel,\n assistantLabel: config.assistantLabel,\n thumbsUpTitle: config.thumbsUpTitle,\n thumbsDownTitle: config.thumbsDownTitle,\n copyTitle: config.copyTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n speechToTextEnabled: config.chatMode === 'AudioInput' || config.chatMode === 'Conversation',\n textToSpeechEnabled: config.chatMode === 'Conversation' || !!config.textToSpeechEnabled,\n ttsVoiceName: config.ttsVoiceName || null,\n audioChunks: [],\n audioPlayQueue: [],\n isPlayingAudio: false,\n currentAudioElement: null,\n currentAudioUrl: null,\n ttsButton: null,\n ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),\n singleResponseMode: !!config.singleResponseMode,\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notificationDismissTimers: {},\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n getStoredWidgetLayout() {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return {};\n }\n\n try {\n var storedLayout = localStorage.getItem(this.chatWidgetLayoutKey);\n return storedLayout ? JSON.parse(storedLayout) || {} : {};\n } catch (error) {\n console.warn('Failed to read widget layout state.', error);\n return {};\n }\n },\n saveStoredWidgetLayout(partialLayout) {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return;\n }\n\n var currentLayout = this.getStoredWidgetLayout();\n var nextLayout = Object.assign({}, currentLayout);\n\n if (partialLayout.panel !== undefined) {\n nextLayout.panel = Object.assign({}, currentLayout.panel || {}, partialLayout.panel || {});\n }\n\n if (partialLayout.toggle !== undefined) {\n nextLayout.toggle = Object.assign({}, currentLayout.toggle || {}, partialLayout.toggle || {});\n }\n\n localStorage.setItem(this.chatWidgetLayoutKey, JSON.stringify(nextLayout));\n },\n getElementSize(element, fallbackWidth, fallbackHeight) {\n if (!element) {\n return {\n width: fallbackWidth || 0,\n height: fallbackHeight || 0\n };\n }\n\n var rect = element.getBoundingClientRect();\n var computed = window.getComputedStyle(element);\n\n return {\n width: Math.round(rect.width || parsePixelValue(computed.width) || fallbackWidth || 0),\n height: Math.round(rect.height || parsePixelValue(computed.height) || fallbackHeight || 0)\n };\n },\n clampWidgetPosition(left, top, width, height) {\n var viewportPadding = 8;\n var maxLeft = Math.max(viewportPadding, window.innerWidth - width - viewportPadding);\n var maxTop = Math.max(viewportPadding, window.innerHeight - height - viewportPadding);\n\n return {\n left: Math.round(clamp(left, viewportPadding, maxLeft)),\n top: Math.round(clamp(top, viewportPadding, maxTop))\n };\n },\n applyAbsolutePosition(element, left, top) {\n if (!element) {\n return;\n }\n\n element.style.left = left + 'px';\n element.style.top = top + 'px';\n element.style.right = 'auto';\n element.style.bottom = 'auto';\n },\n getWidgetDefaultSize() {\n return {\n width: this.widgetDefaultWidth || parsePixelValue(config.widget.defaultWidth) || 380,\n height: this.widgetDefaultHeight || parsePixelValue(config.widget.defaultHeight) || 520\n };\n },\n persistWidgetPanelPosition() {\n if (!this.widgetContainerElement || !config.widget.persistLayout) {\n return;\n }\n\n var panelRect = this.widgetContainerElement.getBoundingClientRect();\n this.saveStoredWidgetLayout({\n panel: {\n left: Math.round(panelRect.left),\n top: Math.round(panelRect.top)\n }\n });\n },\n persistWidgetTogglePosition() {\n if (!this.widgetToggleButtonElement || !config.widget.persistLayout) {\n return;\n }\n\n var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();\n this.saveStoredWidgetLayout({\n toggle: {\n left: Math.round(toggleRect.left),\n top: Math.round(toggleRect.top)\n }\n });\n },\n persistWidgetPanelSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing || !config.widget.persistLayout) {\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n\n this.saveStoredWidgetLayout({\n panel: {\n width: Math.abs(currentSize.width - defaultSize.width) <= 1 ? null : currentSize.width,\n height: Math.abs(currentSize.height - defaultSize.height) <= 1 ? null : currentSize.height\n }\n });\n },\n updateWidgetResetSizeButtonVisibility() {\n if (!this.widgetResetSizeButtonElement) {\n return;\n }\n\n if (!config.widget.enableResizing || !this.widgetContainerElement) {\n this.widgetResetSizeButtonElement.classList.add('d-none');\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n var isResized =\n Math.abs(currentSize.width - defaultSize.width) > 1 ||\n Math.abs(currentSize.height - defaultSize.height) > 1 ||\n !!this.widgetContainerElement.style.width ||\n !!this.widgetContainerElement.style.height;\n\n this.widgetResetSizeButtonElement.classList.toggle('d-none', !isResized);\n },\n resetWidgetSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing) {\n return;\n }\n\n this.widgetContainerElement.style.removeProperty('width');\n this.widgetContainerElement.style.removeProperty('height');\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n restoreWidgetLayout() {\n var storedLayout = this.getStoredWidgetLayout();\n\n if (this.widgetContainerElement && config.widget.enableResizing) {\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.width)) {\n this.widgetContainerElement.style.width = storedLayout.panel.width + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('width');\n }\n\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.height)) {\n this.widgetContainerElement.style.height = storedLayout.panel.height + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('height');\n }\n }\n\n if (this.widgetContainerElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.left) &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.top)) {\n this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top);\n }\n\n if (this.widgetToggleButtonElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) {\n this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.toggle.left, storedLayout.toggle.top);\n }\n\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n attachDraggableWidgetElement(element, handle, layoutKey, suppressClickOnDrag) {\n if (!element || !handle || !config.widget.enableDragging) {\n return;\n }\n\n var activePointerId = null;\n var startX = 0;\n var startY = 0;\n var startLeft = 0;\n var startTop = 0;\n var dragged = false;\n var dragThreshold = 4;\n var interactiveSelector = 'button, a, input, textarea, select, option, label';\n\n var stopDragging = (event) => {\n if (activePointerId === null) {\n return;\n }\n\n if (event && event.pointerId !== undefined && event.pointerId !== activePointerId) {\n return;\n }\n\n document.removeEventListener('pointermove', onPointerMove);\n document.removeEventListener('pointerup', stopDragging);\n document.removeEventListener('pointercancel', stopDragging);\n element.classList.remove('ai-chat-widget-dragging');\n activePointerId = null;\n\n if (!dragged) {\n return;\n }\n\n if (layoutKey === 'panel') {\n this.persistWidgetPanelPosition();\n } else if (layoutKey === 'toggle') {\n this.persistWidgetTogglePosition();\n }\n\n if (suppressClickOnDrag) {\n element.dataset.dragSuppressClick = 'true';\n window.setTimeout(() => {\n if (element.dataset.dragSuppressClick === 'true') {\n element.dataset.dragSuppressClick = 'false';\n }\n }, 0);\n }\n };\n\n var onPointerMove = (event) => {\n if (activePointerId === null || event.pointerId !== activePointerId) {\n return;\n }\n\n var deltaX = event.clientX - startX;\n var deltaY = event.clientY - startY;\n\n if (!dragged && Math.hypot(deltaX, deltaY) < dragThreshold) {\n return;\n }\n\n dragged = true;\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(\n element,\n layoutKey === 'panel' ? defaultSize.width : 52,\n layoutKey === 'panel' ? defaultSize.height : 52);\n var nextPosition = this.clampWidgetPosition(\n startLeft + deltaX,\n startTop + deltaY,\n currentSize.width,\n currentSize.height);\n\n this.applyAbsolutePosition(element, nextPosition.left, nextPosition.top);\n };\n\n handle.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) {\n return;\n }\n\n if (layoutKey === 'panel' && event.target.closest(interactiveSelector)) {\n return;\n }\n\n var rect = element.getBoundingClientRect();\n startX = event.clientX;\n startY = event.clientY;\n startLeft = rect.left;\n startTop = rect.top;\n dragged = false;\n activePointerId = event.pointerId;\n element.classList.add('ai-chat-widget-dragging');\n\n if (handle.setPointerCapture) {\n handle.setPointerCapture(event.pointerId);\n }\n\n document.addEventListener('pointermove', onPointerMove);\n document.addEventListener('pointerup', stopDragging);\n document.addEventListener('pointercancel', stopDragging);\n event.preventDefault();\n });\n },\n constrainWidgetElementsToViewport() {\n if (this.widgetContainerElement && this.widgetContainerElement.style.left) {\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var panelRect = this.widgetContainerElement.getBoundingClientRect();\n var clampedPanel = this.clampWidgetPosition(panelRect.left, panelRect.top, panelSize.width, panelSize.height);\n\n this.applyAbsolutePosition(this.widgetContainerElement, clampedPanel.left, clampedPanel.top);\n\n if (config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n }\n }\n\n if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) {\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();\n var clampedToggle = this.clampWidgetPosition(toggleRect.left, toggleRect.top, toggleSize.width, toggleSize.height);\n\n this.applyAbsolutePosition(this.widgetToggleButtonElement, clampedToggle.left, clampedToggle.top);\n\n if (config.widget.persistLayout) {\n this.persistWidgetTogglePosition();\n }\n }\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(e.dataTransfer.files);\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files;\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId && !profileId) {\n console.warn('Cannot upload documents without a session or profile.');\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n if (sessionId) {\n formData.append('sessionId', sessionId);\n } else {\n formData.append('profileId', profileId);\n }\n for (var i = 0; i < files.length; i++) {\n formData.append('files', files[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n // If the server created a new session, initialize it.\n if (result.sessionId && !sessionId) {\n this.initializeSession(result.sessionId);\n }\n\n if (result.uploaded && result.uploaded.length > 0) {\n for (var j = 0; j < result.uploaded.length; j++) {\n this.documents.push(result.uploaded[j]);\n }\n }\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) this.documents.splice(idx, 1);\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n this.renderDocumentBar();\n }\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '
';\n html += '
';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '';\n html += ' ';\n html += this.escapeHtml(name);\n html += ' ';\n html += '';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '';\n html += ' ';\n html += this.escapeHtml(failedName);\n html += ' ';\n html += '';\n }\n\n if (this.isUploading) {\n html += '';\n html += ' Uploading...';\n html += '';\n }\n\n html += '';\n html += '
';\n if (config.supportedExtensionsText) {\n html += '
Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '
';\n }\n\n html += '
';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // If this is a widget with a stale cached session (e.g., profile was deleted),\n // clear the cached session and start fresh with the current profile.\n if (this.widgetIsInitialized && !this.isSessionStarted && !this._attemptedSessionRecovery) {\n this._attemptedSessionRecovery = true;\n localStorage.removeItem(this.chatWidgetStateSession);\n this.startNewSession();\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n var html = '

' + escaped + '

';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.content = this._conversationAssistantMessage.content;\n msg.htmlContent = parseMarkdownContent(msg.content, msg);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n let processedContent = message.content.trim();\n message.references = normalizeReferences(message.references);\n\n if (message.references && typeof message.references === \"object\" && Object.keys(message.references).length) {\n\n // Only include references that were actually cited in the response.\n const citedRefs = Object.entries(message.references).filter(([key]) => processedContent.includes(key));\n\n if (citedRefs.length) {\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders.\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processedContent = processedContent.replaceAll(value._placeholder, `${value._displayIndex}`);\n }\n\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n processedContent = processedContent.replaceAll('', ',');\n\n processedContent += '

';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processedContent += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})
`\n : `**${value._displayIndex}**. ${label}
`;\n }\n }\n }\n\n message.content = processedContent;\n message.htmlContent = parseMarkdownContent(processedContent, message);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n let processedContent = chunk.content;\n\n for (const [key, value] of Object.entries(references)) {\n processedContent = processedContent.replaceAll(key, `${value.index}`);\n }\n\n // Append processed content to the message.\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n content += processedContent.replaceAll('
', ',');\n }\n\n // Update the existing message\n message.content = content;\n\n message.htmlContent = parseMarkdownContent(content, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n const content = message.content || '';\n\n // Only include references that were actually cited in the response.\n // Check both raw [doc:N] markers and already-rendered tags from streaming.\n const citedRefs = Object.entries(references).filter(([key, value]) =>\n content.includes(key) || content.includes(`${value.index}`)\n );\n\n if (!citedRefs.length) {\n return;\n }\n\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders to avoid collisions during remapping.\n let processed = content.trim();\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processed = processed.replaceAll(key, placeholder);\n processed = processed.replaceAll(`${value.index}`, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processed = processed.replaceAll(value._placeholder, `${value._displayIndex}`);\n }\n\n processed = processed.replaceAll('', ',');\n\n processed += '

';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processed += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})
`\n : `**${value._displayIndex}**. ${label}
`;\n }\n\n message.content = processed;\n message.htmlContent = parseMarkdownContent(processed, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement.getAttribute('data-profile-id');\n },\n setSessionId(sessionId) {\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n if (this.widgetIsInitialized) {\n localStorage.removeItem(this.chatWidgetStateSession);\n }\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => console.error(err));\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n\n if (this.widgetIsInitialized) {\n localStorage.setItem(this.chatWidgetStateSession, sessionId);\n }\n },\n initializeWidget() {\n\n if (!config.widget.chatWidgetContainer) {\n console.error('The widget chatWidgetContainer is required.');\n return;\n }\n\n if (!config.widget.chatWidgetStateName) {\n console.error('The widget chatWidgetStateName is required.');\n return;\n }\n\n const chatWidgetContainer = document.querySelector(config.widget.chatWidgetContainer);\n\n if (!chatWidgetContainer) {\n return;\n }\n\n if (config.widget.chatHistorySection) {\n this.chatHistorySection = document.querySelector(config.widget.chatHistorySection);\n }\n\n this.chatWidgetStateName = config.widget.chatWidgetStateName;\n this.chatWidgetStateSession = config.widget.chatWidgetStateName + 'Session';\n this.chatWidgetLayoutKey = config.widget.chatWidgetStateName + 'Layout';\n this.widgetContainerElement = chatWidgetContainer;\n this.widgetToggleButtonElement = config.widget.toggleButtonSelector\n ? document.querySelector(config.widget.toggleButtonSelector)\n : null;\n this.widgetResetSizeButtonElement = config.widget.resetSizeButtonSelector\n ? document.querySelector(config.widget.resetSizeButtonSelector)\n : null;\n this.widgetDefaultWidth = parsePixelValue(config.widget.defaultWidth) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).width) ||\n 380;\n this.widgetDefaultHeight = parsePixelValue(config.widget.defaultHeight) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).height) ||\n 520;\n this.widgetIsInitialized = true;\n\n if (config.widget.enableResizing) {\n chatWidgetContainer.classList.add('ai-chat-widget-resizable');\n chatWidgetContainer.style.minWidth = (parsePixelValue(config.widget.minWidth) || 320) + 'px';\n chatWidgetContainer.style.minHeight = (parsePixelValue(config.widget.minHeight) || 420) + 'px';\n\n if (typeof ResizeObserver !== 'undefined') {\n this.widgetResizeObserver = new ResizeObserver(() => {\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n });\n\n this.widgetResizeObserver.observe(chatWidgetContainer);\n }\n }\n\n var dragHandleSelector = config.widget.dragHandleSelector || '.ai-chat-widget-header';\n var dragHandle = chatWidgetContainer.querySelector(dragHandleSelector);\n\n if (config.widget.enableDragging && dragHandle) {\n dragHandle.classList.add('ai-chat-widget-drag-handle');\n chatWidgetContainer.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(chatWidgetContainer, dragHandle, 'panel', false);\n }\n\n if (config.widget.enableDragging && this.widgetToggleButtonElement) {\n this.widgetToggleButtonElement.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(this.widgetToggleButtonElement, this.widgetToggleButtonElement, 'toggle', true);\n }\n\n if (this.widgetResetSizeButtonElement) {\n this.widgetResetSizeButtonElement.addEventListener('click', (event) => {\n event.preventDefault();\n this.resetWidgetSize();\n });\n }\n\n this.restoreWidgetLayout();\n\n if (!this.widgetViewportResizeHandler) {\n this.widgetViewportResizeHandler = () => {\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n };\n\n window.addEventListener('resize', this.widgetViewportResizeHandler);\n }\n\n // Auto-load the last session so the user always sees previous chat history.\n this.reloadCurrentSession();\n\n if (config.autoCreateSession && !this.getSessionId()) {\n this.startNewSession();\n }\n\n if (config.widget.showHistoryButton && this.chatHistorySection) {\n\n const showHistoryButton = document.querySelector(config.widget.showHistoryButton);\n\n if (showHistoryButton) {\n showHistoryButton.addEventListener('click', () => {\n this.chatHistorySection.classList.toggle('show');\n });\n }\n\n if (config.widget.closeHistoryButton) {\n var closeHistoryButton = document.querySelector(config.widget.closeHistoryButton);\n\n if (closeHistoryButton) {\n closeHistoryButton.addEventListener('click', () => {\n this.showChatScreen();\n });\n }\n }\n }\n\n if (config.widget.newChatButton) {\n const newChatButton = document.querySelector(config.widget.newChatButton);\n\n if (newChatButton) {\n newChatButton.addEventListener('click', () => {\n this.resetSession();\n this.showChatScreen();\n });\n }\n }\n },\n showChatScreen() {\n\n if (!this.chatHistorySection) {\n return;\n }\n\n this.chatHistorySection.classList.remove('show');\n },\n getSessionId() {\n let sessionId = this.inputElement.getAttribute('data-session-id');\n\n if (!sessionId && this.widgetIsInitialized) {\n sessionId = localStorage.getItem(this.chatWidgetStateSession);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n navigator.clipboard.writeText(message);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Font Awesome SVG+JS replaces with , so we must replace\n // the entire button content and let Font Awesome re-process.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('i');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('i');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n\n // Trigger Font Awesome SVG+JS to convert the new elements.\n if (window.FontAwesome && FontAwesome.dom && FontAwesome.dom.i2svg) {\n FontAwesome.dom.i2svg({ node: container });\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() { this.renderDocumentBar(); },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n if (hasWidgetConfig) {\n this.initializeWidget();\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} +{"version":3,"sources":["ai-chat.js"],"names":["e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","setPrototypeOf","__proto__","displayName","_regenerator","w","m","defineProperty","_regeneratorDefine","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_createForOfIteratorHelper","Array","isArray","_unsupportedIterableToArray","_n","F","s","next","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_nonIterableSpread","from","_arrayLikeToArray","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","parsePixelValue","Number","isFinite","parsed","parseFloat","clamp","min","max","Math","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$link","normalized","assign","index","Index","Text","link","Link","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","renderer","marked","Renderer","data","href","concat","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","__chartConfigs","createChartHtml","chartId","use","extensions","level","start","idx","indexOf","undefined","tokenizer","extracted","tryExtractChartMarker","startIndex","type","raw","substring","endIndex","json","token","config","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","renderChartsInMessage","message","charts","requestAnimationFrame","_iterator","_step","renderChartOnCanvas","err","canvas","getElementById","Chart","console","warn","offsetParent","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","renderPendingCharts","configs","_i2","_Object$keys","keys","parseMarkdownContent","content","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","initialize","instanceConfig","hasWidgetConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","app","Vue","createApp","inputElement","buttonElement","chatContainer","placeholder","isSessionStarted","isPlaceholderVisible","chatWidgetStateSession","chatWidgetLayoutKey","widgetContainerElement","widgetToggleButtonElement","widgetResetSizeButtonElement","widgetResizeObserver","widgetViewportResizeHandler","widgetDefaultWidth","widgetDefaultHeight","widgetIsInitialized","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","getStoredWidgetLayout","storedLayout","localStorage","getItem","saveStoredWidgetLayout","partialLayout","currentLayout","nextLayout","panel","position","setItem","stringify","getElementSize","element","fallbackWidth","fallbackHeight","width","height","rect","getBoundingClientRect","getComputedStyle","round","getElementPosition","left","top","inlineLeft","style","inlineTop","computedLeft","computedTop","isHidden","display","clampWidgetPosition","viewportPadding","maxLeft","innerWidth","maxTop","innerHeight","applyAbsolutePosition","right","bottom","getWidgetDefaultSize","getWidgetToggleGap","isWidgetPanelVisible","classList","contains","persistWidgetPanelPosition","panelDefaultSize","panelPosition","panelSize","toggleSize","linkedPosition","persistWidgetTogglePosition","toggleRect","persistWidgetPanelSize","defaultSize","currentSize","abs","syncTogglePositionToPanel","syncPanelPositionToToggle","togglePosition","updateWidgetResetSizeButtonVisibility","add","isResized","toggle","resetWidgetSize","removeProperty","constrainWidgetElementsToViewport","restoreWidgetLayout","attachDraggableWidgetElement","handle","layoutKey","suppressClickOnDrag","_this","activePointerId","startX","startY","startLeft","startTop","dragged","dragThreshold","interactiveSelector","stopDragging","event","pointerId","removeEventListener","onPointerMove","remove","dataset","dragSuppressClick","setTimeout","deltaX","clientX","deltaY","clientY","hypot","nextPosition","addEventListener","button","target","closest","setPointerCapture","preventDefault","clampedPanel","clampedToggle","handleDragOver","sessionDocumentsEnabled","stopPropagation","inputArea","handleDragLeave","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","_this2","_callee","sessionId","profileId","formData","response","errorText","uploadError","result","j","_t","_context","uploadDocumentUrl","getSessionId","getProfileId","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","fileName","initializeSession","uploaded","failed","removeDocument","doc","_this3","_callee2","removeError","_t2","_context2","removeDocumentUrl","headers","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","self","closeButtons","querySelectorAll","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","querySelector","div","fallbackMessage","startsWith","title","detail","normalizeAssistantAppearance","appearance","label","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this4","_callee3","_t3","_context3","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","forEach","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","_attemptedSessionRecovery","removeItem","startNewSession","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","escaped","replace","_conversationPartialMessage","hidePlaceholder","htmlContent","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentSession","autoCreateSession","onclose","addMessageInternal","_this5","fireEvent","CustomEvent","_this6","processedContent","citedRefs","filter","_ref4","_ref5","includes","sort","_ref6","_ref7","_ref8","_ref9","b","displayIndex","_iterator2","_step2","_step2$value","replaceAll","_displayIndex","_placeholder","_iterator3","_step3","_step3$value","_iterator4","_step4","_step4$value","addMessages","_this7","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","conversationButtonElement","isIndicator","trimmedPrompt","streamMessage","startRecording","_this8","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee4","uint8Array","base64","_context4","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this9","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_i4","_Object$entries3","_Object$entries3$_i","_this9$stream","processReferences","streamingFinished","synthesizeSpeech","_this9$stream2","getServiceDownMessage","_this0","_ref1","_ref10","_ref11","_ref12","_ref13","_ref14","processed","_iterator5","_step5","_step5$value","_iterator6","_step6","_step6$value","_iterator7","_step7","_step7$value","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","playAudioBlob","totalLength","sum","combined","offset","_iterator8","_step8","set","blob","Blob","_this10","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","nextBlob","shift","conversationModeOnAudioEnded","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this11","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","micSource","createMediaStreamSource","connect","analyser","interruptVolumeThreshold","freqData","frequencyBinCount","getByteFrequencyData","k","avg","_callee5","_context5","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","toLowerCase","location","origin","searchParams","originalLength","removedCount","_this12","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this13","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this14","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","sessionRating","initializeApp","_this15","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","threshold","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","initializeWidget","_this16","ResizeObserver","observe","dragHandle","copyResponse","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","FontAwesome","dom","i2svg","node","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","watch","handler","deep","active","mounted","_this17","_callee6","_context6","beforeUnmount","template","mount","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n
\n
\n
\n
{{ userLabel }}
\n
\n \n {{ getAssistantLabel(message) }}\n
\n
\n

{{ message.title }}

\n
\n \n \n \n \n \n
\n
\n
\n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n \n Assistant\n
\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.link = normalized.link ?? normalized.Link ?? null;\n\n return normalized;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `
${data.text}`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `
${langDisplay}
${highlighted}
`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `
\n \"${alt}\"\n
\n \n \n \n
\n
`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `
`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., ).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});\n const hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isSessionStarted: false,\n isPlaceholderVisible: true,\n chatWidgetStateName: null,\n chatWidgetStateSession: null,\n chatWidgetLayoutKey: null,\n chatHistorySection: null,\n widgetContainerElement: null,\n widgetToggleButtonElement: null,\n widgetResetSizeButtonElement: null,\n widgetResizeObserver: null,\n widgetViewportResizeHandler: null,\n widgetDefaultWidth: null,\n widgetDefaultHeight: null,\n widgetIsInitialized: false,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n notifications: [],\n prompt: '',\n documents: config.existingDocuments || [],\n isUploading: false,\n uploadErrors: [],\n isDragOver: false,\n documentBar: null,\n metricsEnabled: !!config.metricsEnabled,\n userLabel: config.userLabel,\n assistantLabel: config.assistantLabel,\n thumbsUpTitle: config.thumbsUpTitle,\n thumbsDownTitle: config.thumbsDownTitle,\n copyTitle: config.copyTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n speechToTextEnabled: config.chatMode === 'AudioInput' || config.chatMode === 'Conversation',\n textToSpeechEnabled: config.chatMode === 'Conversation' || !!config.textToSpeechEnabled,\n ttsVoiceName: config.ttsVoiceName || null,\n audioChunks: [],\n audioPlayQueue: [],\n isPlayingAudio: false,\n currentAudioElement: null,\n currentAudioUrl: null,\n ttsButton: null,\n ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),\n singleResponseMode: !!config.singleResponseMode,\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notificationDismissTimers: {},\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n getStoredWidgetLayout() {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return {};\n }\n\n try {\n var storedLayout = localStorage.getItem(this.chatWidgetLayoutKey);\n return storedLayout ? JSON.parse(storedLayout) || {} : {};\n } catch (error) {\n console.warn('Failed to read widget layout state.', error);\n return {};\n }\n },\n saveStoredWidgetLayout(partialLayout) {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return;\n }\n\n var currentLayout = this.getStoredWidgetLayout();\n var nextLayout = Object.assign({}, currentLayout);\n\n if (partialLayout.panel !== undefined) {\n nextLayout.panel = Object.assign({}, currentLayout.panel || {}, partialLayout.panel || {});\n }\n\n if (partialLayout.position !== undefined) {\n nextLayout.position = Object.assign({}, currentLayout.position || {}, partialLayout.position || {});\n }\n\n localStorage.setItem(this.chatWidgetLayoutKey, JSON.stringify(nextLayout));\n },\n getElementSize(element, fallbackWidth, fallbackHeight) {\n if (!element) {\n return {\n width: fallbackWidth || 0,\n height: fallbackHeight || 0\n };\n }\n\n var rect = element.getBoundingClientRect();\n var computed = window.getComputedStyle(element);\n\n return {\n width: Math.round(rect.width || parsePixelValue(computed.width) || fallbackWidth || 0),\n height: Math.round(rect.height || parsePixelValue(computed.height) || fallbackHeight || 0)\n };\n },\n getElementPosition(element) {\n if (!element) {\n return {\n left: 0,\n top: 0\n };\n }\n\n var rect = element.getBoundingClientRect();\n var computed = window.getComputedStyle(element);\n var inlineLeft = parsePixelValue(element.style.left);\n var inlineTop = parsePixelValue(element.style.top);\n var computedLeft = parsePixelValue(computed.left);\n var computedTop = parsePixelValue(computed.top);\n var isHidden = computed.display === 'none';\n\n return {\n left: Math.round(\n isHidden && Number.isFinite(inlineLeft)\n ? inlineLeft\n : rect.left || inlineLeft || computedLeft || 0),\n top: Math.round(\n isHidden && Number.isFinite(inlineTop)\n ? inlineTop\n : rect.top || inlineTop || computedTop || 0)\n };\n },\n clampWidgetPosition(left, top, width, height) {\n var viewportPadding = 8;\n var maxLeft = Math.max(viewportPadding, window.innerWidth - width - viewportPadding);\n var maxTop = Math.max(viewportPadding, window.innerHeight - height - viewportPadding);\n\n return {\n left: Math.round(clamp(left, viewportPadding, maxLeft)),\n top: Math.round(clamp(top, viewportPadding, maxTop))\n };\n },\n applyAbsolutePosition(element, left, top) {\n if (!element) {\n return;\n }\n\n element.style.left = left + 'px';\n element.style.top = top + 'px';\n element.style.right = 'auto';\n element.style.bottom = 'auto';\n },\n getWidgetDefaultSize() {\n return {\n width: this.widgetDefaultWidth || parsePixelValue(config.widget.defaultWidth) || 380,\n height: this.widgetDefaultHeight || parsePixelValue(config.widget.defaultHeight) || 520\n };\n },\n getWidgetToggleGap() {\n return 8;\n },\n isWidgetPanelVisible() {\n if (!this.widgetContainerElement) {\n return false;\n }\n\n var computed = window.getComputedStyle(this.widgetContainerElement);\n return this.widgetContainerElement.classList.contains('open') && computed.display !== 'none';\n },\n persistWidgetPanelPosition() {\n if (!this.widgetContainerElement || !config.widget.persistLayout) {\n return;\n }\n\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelPosition = this.getElementPosition(this.widgetContainerElement);\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var linkedPosition = this.clampWidgetPosition(\n panelPosition.left + panelSize.width - toggleSize.width,\n panelPosition.top + panelSize.height + this.getWidgetToggleGap(),\n toggleSize.width,\n toggleSize.height);\n\n this.saveStoredWidgetLayout({\n position: {\n left: linkedPosition.left,\n top: linkedPosition.top\n }\n });\n },\n persistWidgetTogglePosition() {\n if (!this.widgetToggleButtonElement || !config.widget.persistLayout) {\n return;\n }\n\n var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();\n this.saveStoredWidgetLayout({\n position: {\n left: this.getElementPosition(this.widgetToggleButtonElement).left,\n top: this.getElementPosition(this.widgetToggleButtonElement).top\n }\n });\n },\n persistWidgetPanelSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing || !config.widget.persistLayout) {\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n\n this.saveStoredWidgetLayout({\n panel: {\n width: Math.abs(currentSize.width - defaultSize.width) <= 1 ? null : currentSize.width,\n height: Math.abs(currentSize.height - defaultSize.height) <= 1 ? null : currentSize.height\n }\n });\n },\n syncTogglePositionToPanel(persistLayout = true) {\n if (!this.widgetContainerElement || !this.widgetToggleButtonElement) {\n return;\n }\n\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var panelPosition = this.getElementPosition(this.widgetContainerElement);\n var linkedPosition = this.clampWidgetPosition(\n panelPosition.left + panelSize.width - toggleSize.width,\n panelPosition.top + panelSize.height + this.getWidgetToggleGap(),\n toggleSize.width,\n toggleSize.height);\n\n this.applyAbsolutePosition(this.widgetToggleButtonElement, linkedPosition.left, linkedPosition.top);\n\n if (persistLayout && config.widget.persistLayout) {\n this.persistWidgetTogglePosition();\n }\n },\n syncPanelPositionToToggle(persistLayout = true) {\n if (!this.widgetContainerElement || !this.widgetToggleButtonElement) {\n return;\n }\n\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var togglePosition = this.getElementPosition(this.widgetToggleButtonElement);\n var linkedPosition = this.clampWidgetPosition(\n togglePosition.left + toggleSize.width - panelSize.width,\n togglePosition.top - panelSize.height - this.getWidgetToggleGap(),\n panelSize.width,\n panelSize.height);\n\n this.applyAbsolutePosition(this.widgetContainerElement, linkedPosition.left, linkedPosition.top);\n\n if (persistLayout && config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n }\n },\n updateWidgetResetSizeButtonVisibility() {\n if (!this.widgetResetSizeButtonElement) {\n return;\n }\n\n if (!config.widget.enableResizing || !this.widgetContainerElement) {\n this.widgetResetSizeButtonElement.classList.add('d-none');\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n var isResized =\n Math.abs(currentSize.width - defaultSize.width) > 1 ||\n Math.abs(currentSize.height - defaultSize.height) > 1 ||\n !!this.widgetContainerElement.style.width ||\n !!this.widgetContainerElement.style.height;\n\n this.widgetResetSizeButtonElement.classList.toggle('d-none', !isResized);\n },\n resetWidgetSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing) {\n return;\n }\n\n this.widgetContainerElement.style.removeProperty('width');\n this.widgetContainerElement.style.removeProperty('height');\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n restoreWidgetLayout() {\n var storedLayout = this.getStoredWidgetLayout();\n\n if (this.widgetContainerElement && config.widget.enableResizing) {\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.width)) {\n this.widgetContainerElement.style.width = storedLayout.panel.width + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('width');\n }\n\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.height)) {\n this.widgetContainerElement.style.height = storedLayout.panel.height + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('height');\n }\n }\n\n if (this.widgetToggleButtonElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.position && storedLayout.position.left) &&\n Number.isFinite(storedLayout.position && storedLayout.position.top)) {\n this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.position.left, storedLayout.position.top);\n this.syncPanelPositionToToggle(false);\n } else if (this.widgetToggleButtonElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) {\n this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.toggle.left, storedLayout.toggle.top);\n this.syncPanelPositionToToggle(false);\n } else if (this.widgetContainerElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.left) &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.top)) {\n this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top);\n this.syncTogglePositionToPanel(false);\n }\n\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n attachDraggableWidgetElement(element, handle, layoutKey, suppressClickOnDrag) {\n if (!element || !handle || !config.widget.enableDragging) {\n return;\n }\n\n var activePointerId = null;\n var startX = 0;\n var startY = 0;\n var startLeft = 0;\n var startTop = 0;\n var dragged = false;\n var dragThreshold = 4;\n var interactiveSelector = 'button, a, input, textarea, select, option, label';\n\n var stopDragging = (event) => {\n if (activePointerId === null) {\n return;\n }\n\n if (event && event.pointerId !== undefined && event.pointerId !== activePointerId) {\n return;\n }\n\n document.removeEventListener('pointermove', onPointerMove);\n document.removeEventListener('pointerup', stopDragging);\n document.removeEventListener('pointercancel', stopDragging);\n element.classList.remove('ai-chat-widget-dragging');\n activePointerId = null;\n\n if (!dragged) {\n return;\n }\n\n if (layoutKey === 'panel') {\n this.syncTogglePositionToPanel(false);\n this.persistWidgetPanelPosition();\n } else if (layoutKey === 'toggle') {\n this.syncPanelPositionToToggle(false);\n this.persistWidgetTogglePosition();\n }\n\n if (config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n this.persistWidgetTogglePosition();\n }\n\n if (suppressClickOnDrag) {\n element.dataset.dragSuppressClick = 'true';\n window.setTimeout(() => {\n if (element.dataset.dragSuppressClick === 'true') {\n element.dataset.dragSuppressClick = 'false';\n }\n }, 0);\n }\n };\n\n var onPointerMove = (event) => {\n if (activePointerId === null || event.pointerId !== activePointerId) {\n return;\n }\n\n var deltaX = event.clientX - startX;\n var deltaY = event.clientY - startY;\n\n if (!dragged && Math.hypot(deltaX, deltaY) < dragThreshold) {\n return;\n }\n\n dragged = true;\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(\n element,\n layoutKey === 'panel' ? defaultSize.width : 52,\n layoutKey === 'panel' ? defaultSize.height : 52);\n var nextPosition = this.clampWidgetPosition(\n startLeft + deltaX,\n startTop + deltaY,\n currentSize.width,\n currentSize.height);\n\n this.applyAbsolutePosition(element, nextPosition.left, nextPosition.top);\n\n if (layoutKey === 'panel') {\n this.syncTogglePositionToPanel(false);\n } else if (layoutKey === 'toggle') {\n this.syncPanelPositionToToggle(false);\n }\n };\n\n handle.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) {\n return;\n }\n\n if (layoutKey === 'panel' && event.target.closest(interactiveSelector)) {\n return;\n }\n\n var rect = element.getBoundingClientRect();\n startX = event.clientX;\n startY = event.clientY;\n startLeft = rect.left;\n startTop = rect.top;\n dragged = false;\n activePointerId = event.pointerId;\n element.classList.add('ai-chat-widget-dragging');\n\n if (handle.setPointerCapture) {\n handle.setPointerCapture(event.pointerId);\n }\n\n document.addEventListener('pointermove', onPointerMove);\n document.addEventListener('pointerup', stopDragging);\n document.addEventListener('pointercancel', stopDragging);\n event.preventDefault();\n });\n },\n constrainWidgetElementsToViewport() {\n if (this.widgetContainerElement && this.widgetContainerElement.style.left && this.isWidgetPanelVisible()) {\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var panelPosition = this.getElementPosition(this.widgetContainerElement);\n var clampedPanel = this.clampWidgetPosition(panelPosition.left, panelPosition.top, panelSize.width, panelSize.height);\n\n this.applyAbsolutePosition(this.widgetContainerElement, clampedPanel.left, clampedPanel.top);\n this.syncTogglePositionToPanel(false);\n\n if (config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n this.persistWidgetTogglePosition();\n }\n } else if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) {\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var togglePosition = this.getElementPosition(this.widgetToggleButtonElement);\n var clampedToggle = this.clampWidgetPosition(togglePosition.left, togglePosition.top, toggleSize.width, toggleSize.height);\n\n this.applyAbsolutePosition(this.widgetToggleButtonElement, clampedToggle.left, clampedToggle.top);\n this.syncPanelPositionToToggle(false);\n\n if (config.widget.persistLayout) {\n this.persistWidgetTogglePosition();\n this.persistWidgetPanelPosition();\n }\n }\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(e.dataTransfer.files);\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files;\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId && !profileId) {\n console.warn('Cannot upload documents without a session or profile.');\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n if (sessionId) {\n formData.append('sessionId', sessionId);\n } else {\n formData.append('profileId', profileId);\n }\n for (var i = 0; i < files.length; i++) {\n formData.append('files', files[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n // If the server created a new session, initialize it.\n if (result.sessionId && !sessionId) {\n this.initializeSession(result.sessionId);\n }\n\n if (result.uploaded && result.uploaded.length > 0) {\n for (var j = 0; j < result.uploaded.length; j++) {\n this.documents.push(result.uploaded[j]);\n }\n }\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) this.documents.splice(idx, 1);\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n this.renderDocumentBar();\n }\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '
';\n html += '
';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '';\n html += ' ';\n html += this.escapeHtml(name);\n html += ' ';\n html += '';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '';\n html += ' ';\n html += this.escapeHtml(failedName);\n html += ' ';\n html += '';\n }\n\n if (this.isUploading) {\n html += '';\n html += ' Uploading...';\n html += '';\n }\n\n html += '';\n html += '
';\n if (config.supportedExtensionsText) {\n html += '
Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '
';\n }\n\n html += '
';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // If this is a widget with a stale cached session (e.g., profile was deleted),\n // clear the cached session and start fresh with the current profile.\n if (this.widgetIsInitialized && !this.isSessionStarted && !this._attemptedSessionRecovery) {\n this._attemptedSessionRecovery = true;\n localStorage.removeItem(this.chatWidgetStateSession);\n this.startNewSession();\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n var html = '

' + escaped + '

';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.content = this._conversationAssistantMessage.content;\n msg.htmlContent = parseMarkdownContent(msg.content, msg);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n let processedContent = message.content.trim();\n message.references = normalizeReferences(message.references);\n\n if (message.references && typeof message.references === \"object\" && Object.keys(message.references).length) {\n\n // Only include references that were actually cited in the response.\n const citedRefs = Object.entries(message.references).filter(([key]) => processedContent.includes(key));\n\n if (citedRefs.length) {\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders.\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processedContent = processedContent.replaceAll(value._placeholder, `${value._displayIndex}`);\n }\n\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n processedContent = processedContent.replaceAll('
', ',');\n\n processedContent += '

';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processedContent += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})
`\n : `**${value._displayIndex}**. ${label}
`;\n }\n }\n }\n\n message.content = processedContent;\n message.htmlContent = parseMarkdownContent(processedContent, message);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n let processedContent = chunk.content;\n\n for (const [key, value] of Object.entries(references)) {\n processedContent = processedContent.replaceAll(key, `${value.index}`);\n }\n\n // Append processed content to the message.\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n content += processedContent.replaceAll('
', ',');\n }\n\n // Update the existing message\n message.content = content;\n\n message.htmlContent = parseMarkdownContent(content, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n const content = message.content || '';\n\n // Only include references that were actually cited in the response.\n // Check both raw [doc:N] markers and already-rendered tags from streaming.\n const citedRefs = Object.entries(references).filter(([key, value]) =>\n content.includes(key) || content.includes(`${value.index}`)\n );\n\n if (!citedRefs.length) {\n return;\n }\n\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders to avoid collisions during remapping.\n let processed = content.trim();\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processed = processed.replaceAll(key, placeholder);\n processed = processed.replaceAll(`${value.index}`, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processed = processed.replaceAll(value._placeholder, `${value._displayIndex}`);\n }\n\n processed = processed.replaceAll('', ',');\n\n processed += '

';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processed += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})
`\n : `**${value._displayIndex}**. ${label}
`;\n }\n\n message.content = processed;\n message.htmlContent = parseMarkdownContent(processed, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement.getAttribute('data-profile-id');\n },\n setSessionId(sessionId) {\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n if (this.widgetIsInitialized) {\n localStorage.removeItem(this.chatWidgetStateSession);\n }\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => console.error(err));\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n\n if (this.widgetIsInitialized) {\n localStorage.setItem(this.chatWidgetStateSession, sessionId);\n }\n },\n initializeWidget() {\n\n if (!config.widget.chatWidgetContainer) {\n console.error('The widget chatWidgetContainer is required.');\n return;\n }\n\n if (!config.widget.chatWidgetStateName) {\n console.error('The widget chatWidgetStateName is required.');\n return;\n }\n\n const chatWidgetContainer = document.querySelector(config.widget.chatWidgetContainer);\n\n if (!chatWidgetContainer) {\n return;\n }\n\n if (config.widget.chatHistorySection) {\n this.chatHistorySection = document.querySelector(config.widget.chatHistorySection);\n }\n\n this.chatWidgetStateName = config.widget.chatWidgetStateName;\n this.chatWidgetStateSession = config.widget.chatWidgetStateName + 'Session';\n this.chatWidgetLayoutKey = config.widget.chatWidgetStateName + 'Layout';\n this.widgetContainerElement = chatWidgetContainer;\n this.widgetToggleButtonElement = config.widget.toggleButtonSelector\n ? document.querySelector(config.widget.toggleButtonSelector)\n : null;\n this.widgetResetSizeButtonElement = config.widget.resetSizeButtonSelector\n ? document.querySelector(config.widget.resetSizeButtonSelector)\n : null;\n this.widgetDefaultWidth = parsePixelValue(config.widget.defaultWidth) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).width) ||\n 380;\n this.widgetDefaultHeight = parsePixelValue(config.widget.defaultHeight) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).height) ||\n 520;\n this.widgetIsInitialized = true;\n\n if (config.widget.enableResizing) {\n chatWidgetContainer.classList.add('ai-chat-widget-resizable');\n chatWidgetContainer.style.minWidth = (parsePixelValue(config.widget.minWidth) || 320) + 'px';\n chatWidgetContainer.style.minHeight = (parsePixelValue(config.widget.minHeight) || 420) + 'px';\n\n if (typeof ResizeObserver !== 'undefined') {\n this.widgetResizeObserver = new ResizeObserver(() => {\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n });\n\n this.widgetResizeObserver.observe(chatWidgetContainer);\n }\n }\n\n var dragHandleSelector = config.widget.dragHandleSelector || '.ai-chat-widget-header';\n var dragHandle = chatWidgetContainer.querySelector(dragHandleSelector);\n\n if (config.widget.enableDragging && dragHandle) {\n dragHandle.classList.add('ai-chat-widget-drag-handle');\n chatWidgetContainer.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(chatWidgetContainer, dragHandle, 'panel', false);\n }\n\n if (config.widget.enableDragging && this.widgetToggleButtonElement) {\n this.widgetToggleButtonElement.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(this.widgetToggleButtonElement, this.widgetToggleButtonElement, 'toggle', true);\n }\n\n if (this.widgetResetSizeButtonElement) {\n this.widgetResetSizeButtonElement.addEventListener('click', (event) => {\n event.preventDefault();\n this.resetWidgetSize();\n });\n }\n\n this.restoreWidgetLayout();\n\n if (!this.widgetViewportResizeHandler) {\n this.widgetViewportResizeHandler = () => {\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n };\n\n window.addEventListener('resize', this.widgetViewportResizeHandler);\n }\n\n // Auto-load the last session so the user always sees previous chat history.\n this.reloadCurrentSession();\n\n if (config.autoCreateSession && !this.getSessionId()) {\n this.startNewSession();\n }\n\n if (config.widget.showHistoryButton && this.chatHistorySection) {\n\n const showHistoryButton = document.querySelector(config.widget.showHistoryButton);\n\n if (showHistoryButton) {\n showHistoryButton.addEventListener('click', () => {\n this.chatHistorySection.classList.toggle('show');\n });\n }\n\n if (config.widget.closeHistoryButton) {\n var closeHistoryButton = document.querySelector(config.widget.closeHistoryButton);\n\n if (closeHistoryButton) {\n closeHistoryButton.addEventListener('click', () => {\n this.showChatScreen();\n });\n }\n }\n }\n\n if (config.widget.newChatButton) {\n const newChatButton = document.querySelector(config.widget.newChatButton);\n\n if (newChatButton) {\n newChatButton.addEventListener('click', () => {\n this.resetSession();\n this.showChatScreen();\n });\n }\n }\n },\n showChatScreen() {\n\n if (!this.chatHistorySection) {\n return;\n }\n\n this.chatHistorySection.classList.remove('show');\n },\n getSessionId() {\n let sessionId = this.inputElement.getAttribute('data-session-id');\n\n if (!sessionId && this.widgetIsInitialized) {\n sessionId = localStorage.getItem(this.chatWidgetStateSession);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n navigator.clipboard.writeText(message);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Font Awesome SVG+JS replaces with , so we must replace\n // the entire button content and let Font Awesome re-process.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('i');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('i');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n\n // Trigger Font Awesome SVG+JS to convert the new elements.\n if (window.FontAwesome && FontAwesome.dom && FontAwesome.dom.i2svg) {\n FontAwesome.dom.i2svg({ node: container });\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() { this.renderDocumentBar(); },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n if (hasWidgetConfig) {\n this.initializeWidget();\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js index fab50da4..d61480a2 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/scripts/ai-chat.min.js @@ -1,2 +1,2 @@ -function _regenerator(){/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */var e,t,n="function"==typeof Symbol?Symbol:{},i=n.iterator||"@@iterator",o=n.toStringTag||"@@toStringTag";function s(n,i,o,s){var l=i&&i.prototype instanceof r?i:r,c=Object.create(l.prototype);return _regeneratorDefine2(c,"_invoke",function(n,i,o){var s,r,l,c=0,d=o||[],u=!1,h={p:0,n:0,v:e,a:g,f:g.bind(e,4),d:function(t,n){return s=t,r=0,l=e,h.n=n,a}};function g(n,i){for(r=n,l=i,t=0;!u&&c&&!o&&t3?(o=m===i)&&(l=s[(r=s[4])?5:(r=3,3)],s[4]=s[5]=e):s[0]<=g&&((o=n<2&&gi||i>m)&&(s[4]=n,s[5]=i,h.n=m,r=0))}if(o||n>1)return a;throw u=!0,i}return function(o,d,m){if(c>1)throw TypeError("Generator is already running");for(u&&1===d&&g(d,m),r=d,l=m;(t=r<2?e:l)||!u;){s||(r?r<3?(r>1&&(h.n=-1),g(r,l)):h.n=l:h.v=l);try{if(c=2,s){if(r||(o="next"),t=s[o]){if(!(t=t.call(s,l)))throw TypeError("iterator result is not an object");if(!t.done)return t;l=t.value,r<2&&(r=0)}else 1===r&&(t=s.return)&&t.call(s),r<2&&(l=TypeError("The iterator does not provide a '"+o+"' method"),r=1);s=e}else if((t=(u=h.n<0)?l:n.call(i,h))!==a)break}catch(t){s=e,r=1,l=t}finally{c=1}}return{value:t,done:u}}}(n,o,s),!0),c}var a={};function r(){}function l(){}function c(){}t=Object.getPrototypeOf;var d=[][i]?t(t([][i]())):(_regeneratorDefine2(t={},i,function(){return this}),t),u=c.prototype=r.prototype=Object.create(d);function h(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,c):(e.__proto__=c,_regeneratorDefine2(e,o,"GeneratorFunction")),e.prototype=Object.create(u),e}return l.prototype=c,_regeneratorDefine2(u,"constructor",c),_regeneratorDefine2(c,"constructor",l),l.displayName="GeneratorFunction",_regeneratorDefine2(c,o,"GeneratorFunction"),_regeneratorDefine2(u),_regeneratorDefine2(u,o,"Generator"),_regeneratorDefine2(u,i,function(){return this}),_regeneratorDefine2(u,"toString",function(){return"[object Generator]"}),(_regenerator=function(){return{w:s,m:h}})()}function _regeneratorDefine2(e,t,n,i){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}_regeneratorDefine2=function(e,t,n,i){function s(t,n){_regeneratorDefine2(e,t,function(e){return this._invoke(t,n,e)})}t?o?o(e,t,{value:n,enumerable:!i,configurable:!i,writable:!i}):e[t]=n:(s("next",0),s("throw",1),s("return",2))},_regeneratorDefine2(e,t,n,i)}function asyncGeneratorStep(e,t,n,i,o,s,a){try{var r=e[s](a),l=r.value}catch(e){return void n(e)}r.done?t(l):Promise.resolve(l).then(i,o)}function _asyncToGenerator(e){return function(){var t=this,n=arguments;return new Promise(function(i,o){var s=e.apply(t,n);function a(e){asyncGeneratorStep(s,i,o,a,r,"next",e)}function r(e){asyncGeneratorStep(s,i,o,a,r,"throw",e)}a(void 0)})}}function _createForOfIteratorHelper(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var i=0,o=function(){};return{s:o,n:function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,a=!0,r=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return a=e.done,e},e:function(e){r=!0,s=e},f:function(){try{a||null==n.return||n.return()}finally{if(r)throw s}}}}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=Array(t);n\n
\n
\n
{{ userLabel }}
\n
\n \n {{ getAssistantLabel(message) }}\n
\n
\n

{{ message.title }}

\n
\n \n \n \n \n \n
\n
\n
\n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n \n ',indicatorTemplate:'\n
\n \n Assistant\n
\n '};function t(e){if(!e)return"";var t=e.trim();return/^javascript:/i.test(t)||/^vbscript:/i.test(t)||/^data:text\/html/i.test(t)?"":e}function n(e){var t=document.createElement("span");return t.textContent=e,t.innerHTML}function i(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"!=typeof e)return null;var t=parseFloat(e);return Number.isFinite(t)?t:null}function o(e,t,n){return Math.min(Math.max(e,t),n)}function s(e){var t,n,i,o,s,a;if(!e||"object"!==_typeof(e))return null;var r=Object.assign({},e);return r.index=null!==(t=null!==(n=r.index)&&void 0!==n?n:r.Index)&&void 0!==t?t:0,r.text=null!==(i=null!==(o=r.text)&&void 0!==o?o:r.Text)&&void 0!==i?i:null,r.link=null!==(s=null!==(a=r.link)&&void 0!==a?a:r.Link)&&void 0!==s?s:null,r}function a(e){if(!e||"object"!==_typeof(e))return{};for(var t={},n=0,i=Object.entries(e);n').concat(e.text,"
"):e.text||""},r.code=function(e){var t=e.text||"",i=(e.lang||"").trim(),o=t;if("undefined"!=typeof hljs)if(i&&hljs.getLanguage(i))try{o=hljs.highlight(t,{language:i}).value}catch(e){}else try{o=hljs.highlightAuto(t).value}catch(e){}else o=n(t);var s=i?n(i):"code";return'
'.concat(s,'
').concat(o,"
")},r.image=function(n){var i=t(n.href);if(!i)return"";var o=n.text||e.generatedImageAltText,s=e.generatedImageMaxWidth;return'
\n ').concat(o,'\n
\n \n \n \n
\n
')};var l=0,c=[];function d(e){if(e&&e._pendingCharts&&e._pendingCharts.length){var t=_toConsumableArray(e._pendingCharts);e._pendingCharts=[],requestAnimationFrame(function(){var e,n=_createForOfIteratorHelper(t);try{for(n.s();!(e=n.n()).done;){var i=e.value;u(i.chartId,i.config)}}catch(e){n.e(e)}finally{n.f()}})}}function u(e,t){var n=document.getElementById(e);if(!n)return!1;if("undefined"==typeof Chart)return console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., ).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});\n const hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isSessionStarted: false,\n isPlaceholderVisible: true,\n chatWidgetStateName: null,\n chatWidgetStateSession: null,\n chatWidgetLayoutKey: null,\n chatHistorySection: null,\n widgetContainerElement: null,\n widgetToggleButtonElement: null,\n widgetResetSizeButtonElement: null,\n widgetResizeObserver: null,\n widgetViewportResizeHandler: null,\n widgetDefaultWidth: null,\n widgetDefaultHeight: null,\n widgetIsInitialized: false,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n notifications: [],\n prompt: '',\n documents: config.existingDocuments || [],\n isUploading: false,\n uploadErrors: [],\n isDragOver: false,\n documentBar: null,\n metricsEnabled: !!config.metricsEnabled,\n userLabel: config.userLabel,\n assistantLabel: config.assistantLabel,\n thumbsUpTitle: config.thumbsUpTitle,\n thumbsDownTitle: config.thumbsDownTitle,\n copyTitle: config.copyTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n speechToTextEnabled: config.chatMode === 'AudioInput' || config.chatMode === 'Conversation',\n textToSpeechEnabled: config.chatMode === 'Conversation' || !!config.textToSpeechEnabled,\n ttsVoiceName: config.ttsVoiceName || null,\n audioChunks: [],\n audioPlayQueue: [],\n isPlayingAudio: false,\n currentAudioElement: null,\n currentAudioUrl: null,\n ttsButton: null,\n ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),\n singleResponseMode: !!config.singleResponseMode,\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notificationDismissTimers: {},\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n getStoredWidgetLayout() {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return {};\n }\n\n try {\n var storedLayout = localStorage.getItem(this.chatWidgetLayoutKey);\n return storedLayout ? JSON.parse(storedLayout) || {} : {};\n } catch (error) {\n console.warn('Failed to read widget layout state.', error);\n return {};\n }\n },\n saveStoredWidgetLayout(partialLayout) {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return;\n }\n\n var currentLayout = this.getStoredWidgetLayout();\n var nextLayout = Object.assign({}, currentLayout);\n\n if (partialLayout.panel !== undefined) {\n nextLayout.panel = Object.assign({}, currentLayout.panel || {}, partialLayout.panel || {});\n }\n\n if (partialLayout.toggle !== undefined) {\n nextLayout.toggle = Object.assign({}, currentLayout.toggle || {}, partialLayout.toggle || {});\n }\n\n localStorage.setItem(this.chatWidgetLayoutKey, JSON.stringify(nextLayout));\n },\n getElementSize(element, fallbackWidth, fallbackHeight) {\n if (!element) {\n return {\n width: fallbackWidth || 0,\n height: fallbackHeight || 0\n };\n }\n\n var rect = element.getBoundingClientRect();\n var computed = window.getComputedStyle(element);\n\n return {\n width: Math.round(rect.width || parsePixelValue(computed.width) || fallbackWidth || 0),\n height: Math.round(rect.height || parsePixelValue(computed.height) || fallbackHeight || 0)\n };\n },\n clampWidgetPosition(left, top, width, height) {\n var viewportPadding = 8;\n var maxLeft = Math.max(viewportPadding, window.innerWidth - width - viewportPadding);\n var maxTop = Math.max(viewportPadding, window.innerHeight - height - viewportPadding);\n\n return {\n left: Math.round(clamp(left, viewportPadding, maxLeft)),\n top: Math.round(clamp(top, viewportPadding, maxTop))\n };\n },\n applyAbsolutePosition(element, left, top) {\n if (!element) {\n return;\n }\n\n element.style.left = left + 'px';\n element.style.top = top + 'px';\n element.style.right = 'auto';\n element.style.bottom = 'auto';\n },\n getWidgetDefaultSize() {\n return {\n width: this.widgetDefaultWidth || parsePixelValue(config.widget.defaultWidth) || 380,\n height: this.widgetDefaultHeight || parsePixelValue(config.widget.defaultHeight) || 520\n };\n },\n persistWidgetPanelPosition() {\n if (!this.widgetContainerElement || !config.widget.persistLayout) {\n return;\n }\n\n var panelRect = this.widgetContainerElement.getBoundingClientRect();\n this.saveStoredWidgetLayout({\n panel: {\n left: Math.round(panelRect.left),\n top: Math.round(panelRect.top)\n }\n });\n },\n persistWidgetTogglePosition() {\n if (!this.widgetToggleButtonElement || !config.widget.persistLayout) {\n return;\n }\n\n var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();\n this.saveStoredWidgetLayout({\n toggle: {\n left: Math.round(toggleRect.left),\n top: Math.round(toggleRect.top)\n }\n });\n },\n persistWidgetPanelSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing || !config.widget.persistLayout) {\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n\n this.saveStoredWidgetLayout({\n panel: {\n width: Math.abs(currentSize.width - defaultSize.width) <= 1 ? null : currentSize.width,\n height: Math.abs(currentSize.height - defaultSize.height) <= 1 ? null : currentSize.height\n }\n });\n },\n updateWidgetResetSizeButtonVisibility() {\n if (!this.widgetResetSizeButtonElement) {\n return;\n }\n\n if (!config.widget.enableResizing || !this.widgetContainerElement) {\n this.widgetResetSizeButtonElement.classList.add('d-none');\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n var isResized =\n Math.abs(currentSize.width - defaultSize.width) > 1 ||\n Math.abs(currentSize.height - defaultSize.height) > 1 ||\n !!this.widgetContainerElement.style.width ||\n !!this.widgetContainerElement.style.height;\n\n this.widgetResetSizeButtonElement.classList.toggle('d-none', !isResized);\n },\n resetWidgetSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing) {\n return;\n }\n\n this.widgetContainerElement.style.removeProperty('width');\n this.widgetContainerElement.style.removeProperty('height');\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n restoreWidgetLayout() {\n var storedLayout = this.getStoredWidgetLayout();\n\n if (this.widgetContainerElement && config.widget.enableResizing) {\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.width)) {\n this.widgetContainerElement.style.width = storedLayout.panel.width + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('width');\n }\n\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.height)) {\n this.widgetContainerElement.style.height = storedLayout.panel.height + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('height');\n }\n }\n\n if (this.widgetContainerElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.left) &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.top)) {\n this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top);\n }\n\n if (this.widgetToggleButtonElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) {\n this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.toggle.left, storedLayout.toggle.top);\n }\n\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n attachDraggableWidgetElement(element, handle, layoutKey, suppressClickOnDrag) {\n if (!element || !handle || !config.widget.enableDragging) {\n return;\n }\n\n var activePointerId = null;\n var startX = 0;\n var startY = 0;\n var startLeft = 0;\n var startTop = 0;\n var dragged = false;\n var dragThreshold = 4;\n var interactiveSelector = 'button, a, input, textarea, select, option, label';\n\n var stopDragging = (event) => {\n if (activePointerId === null) {\n return;\n }\n\n if (event && event.pointerId !== undefined && event.pointerId !== activePointerId) {\n return;\n }\n\n document.removeEventListener('pointermove', onPointerMove);\n document.removeEventListener('pointerup', stopDragging);\n document.removeEventListener('pointercancel', stopDragging);\n element.classList.remove('ai-chat-widget-dragging');\n activePointerId = null;\n\n if (!dragged) {\n return;\n }\n\n if (layoutKey === 'panel') {\n this.persistWidgetPanelPosition();\n } else if (layoutKey === 'toggle') {\n this.persistWidgetTogglePosition();\n }\n\n if (suppressClickOnDrag) {\n element.dataset.dragSuppressClick = 'true';\n window.setTimeout(() => {\n if (element.dataset.dragSuppressClick === 'true') {\n element.dataset.dragSuppressClick = 'false';\n }\n }, 0);\n }\n };\n\n var onPointerMove = (event) => {\n if (activePointerId === null || event.pointerId !== activePointerId) {\n return;\n }\n\n var deltaX = event.clientX - startX;\n var deltaY = event.clientY - startY;\n\n if (!dragged && Math.hypot(deltaX, deltaY) < dragThreshold) {\n return;\n }\n\n dragged = true;\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(\n element,\n layoutKey === 'panel' ? defaultSize.width : 52,\n layoutKey === 'panel' ? defaultSize.height : 52);\n var nextPosition = this.clampWidgetPosition(\n startLeft + deltaX,\n startTop + deltaY,\n currentSize.width,\n currentSize.height);\n\n this.applyAbsolutePosition(element, nextPosition.left, nextPosition.top);\n };\n\n handle.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) {\n return;\n }\n\n if (layoutKey === 'panel' && event.target.closest(interactiveSelector)) {\n return;\n }\n\n var rect = element.getBoundingClientRect();\n startX = event.clientX;\n startY = event.clientY;\n startLeft = rect.left;\n startTop = rect.top;\n dragged = false;\n activePointerId = event.pointerId;\n element.classList.add('ai-chat-widget-dragging');\n\n if (handle.setPointerCapture) {\n handle.setPointerCapture(event.pointerId);\n }\n\n document.addEventListener('pointermove', onPointerMove);\n document.addEventListener('pointerup', stopDragging);\n document.addEventListener('pointercancel', stopDragging);\n event.preventDefault();\n });\n },\n constrainWidgetElementsToViewport() {\n if (this.widgetContainerElement && this.widgetContainerElement.style.left) {\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var panelRect = this.widgetContainerElement.getBoundingClientRect();\n var clampedPanel = this.clampWidgetPosition(panelRect.left, panelRect.top, panelSize.width, panelSize.height);\n\n this.applyAbsolutePosition(this.widgetContainerElement, clampedPanel.left, clampedPanel.top);\n\n if (config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n }\n }\n\n if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) {\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();\n var clampedToggle = this.clampWidgetPosition(toggleRect.left, toggleRect.top, toggleSize.width, toggleSize.height);\n\n this.applyAbsolutePosition(this.widgetToggleButtonElement, clampedToggle.left, clampedToggle.top);\n\n if (config.widget.persistLayout) {\n this.persistWidgetTogglePosition();\n }\n }\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(e.dataTransfer.files);\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files;\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId && !profileId) {\n console.warn('Cannot upload documents without a session or profile.');\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n if (sessionId) {\n formData.append('sessionId', sessionId);\n } else {\n formData.append('profileId', profileId);\n }\n for (var i = 0; i < files.length; i++) {\n formData.append('files', files[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n // If the server created a new session, initialize it.\n if (result.sessionId && !sessionId) {\n this.initializeSession(result.sessionId);\n }\n\n if (result.uploaded && result.uploaded.length > 0) {\n for (var j = 0; j < result.uploaded.length; j++) {\n this.documents.push(result.uploaded[j]);\n }\n }\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) this.documents.splice(idx, 1);\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n this.renderDocumentBar();\n }\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '
';\n html += '
';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '';\n html += ' ';\n html += this.escapeHtml(name);\n html += ' ';\n html += '';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '';\n html += ' ';\n html += this.escapeHtml(failedName);\n html += ' ';\n html += '';\n }\n\n if (this.isUploading) {\n html += '';\n html += ' Uploading...';\n html += '';\n }\n\n html += '';\n html += '
';\n if (config.supportedExtensionsText) {\n html += '
Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '
';\n }\n\n html += '
';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // If this is a widget with a stale cached session (e.g., profile was deleted),\n // clear the cached session and start fresh with the current profile.\n if (this.widgetIsInitialized && !this.isSessionStarted && !this._attemptedSessionRecovery) {\n this._attemptedSessionRecovery = true;\n localStorage.removeItem(this.chatWidgetStateSession);\n this.startNewSession();\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n var html = '

' + escaped + '

';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.content = this._conversationAssistantMessage.content;\n msg.htmlContent = parseMarkdownContent(msg.content, msg);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n let processedContent = message.content.trim();\n message.references = normalizeReferences(message.references);\n\n if (message.references && typeof message.references === \"object\" && Object.keys(message.references).length) {\n\n // Only include references that were actually cited in the response.\n const citedRefs = Object.entries(message.references).filter(([key]) => processedContent.includes(key));\n\n if (citedRefs.length) {\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders.\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processedContent = processedContent.replaceAll(value._placeholder, `${value._displayIndex}`);\n }\n\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n processedContent = processedContent.replaceAll('
', ',');\n\n processedContent += '

';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processedContent += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})
`\n : `**${value._displayIndex}**. ${label}
`;\n }\n }\n }\n\n message.content = processedContent;\n message.htmlContent = parseMarkdownContent(processedContent, message);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n let processedContent = chunk.content;\n\n for (const [key, value] of Object.entries(references)) {\n processedContent = processedContent.replaceAll(key, `${value.index}`);\n }\n\n // Append processed content to the message.\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n content += processedContent.replaceAll('
', ',');\n }\n\n // Update the existing message\n message.content = content;\n\n message.htmlContent = parseMarkdownContent(content, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n const content = message.content || '';\n\n // Only include references that were actually cited in the response.\n // Check both raw [doc:N] markers and already-rendered tags from streaming.\n const citedRefs = Object.entries(references).filter(([key, value]) =>\n content.includes(key) || content.includes(`${value.index}`)\n );\n\n if (!citedRefs.length) {\n return;\n }\n\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders to avoid collisions during remapping.\n let processed = content.trim();\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processed = processed.replaceAll(key, placeholder);\n processed = processed.replaceAll(`${value.index}`, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processed = processed.replaceAll(value._placeholder, `${value._displayIndex}`);\n }\n\n processed = processed.replaceAll('', ',');\n\n processed += '

';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processed += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})
`\n : `**${value._displayIndex}**. ${label}
`;\n }\n\n message.content = processed;\n message.htmlContent = parseMarkdownContent(processed, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement.getAttribute('data-profile-id');\n },\n setSessionId(sessionId) {\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n if (this.widgetIsInitialized) {\n localStorage.removeItem(this.chatWidgetStateSession);\n }\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => console.error(err));\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n\n if (this.widgetIsInitialized) {\n localStorage.setItem(this.chatWidgetStateSession, sessionId);\n }\n },\n initializeWidget() {\n\n if (!config.widget.chatWidgetContainer) {\n console.error('The widget chatWidgetContainer is required.');\n return;\n }\n\n if (!config.widget.chatWidgetStateName) {\n console.error('The widget chatWidgetStateName is required.');\n return;\n }\n\n const chatWidgetContainer = document.querySelector(config.widget.chatWidgetContainer);\n\n if (!chatWidgetContainer) {\n return;\n }\n\n if (config.widget.chatHistorySection) {\n this.chatHistorySection = document.querySelector(config.widget.chatHistorySection);\n }\n\n this.chatWidgetStateName = config.widget.chatWidgetStateName;\n this.chatWidgetStateSession = config.widget.chatWidgetStateName + 'Session';\n this.chatWidgetLayoutKey = config.widget.chatWidgetStateName + 'Layout';\n this.widgetContainerElement = chatWidgetContainer;\n this.widgetToggleButtonElement = config.widget.toggleButtonSelector\n ? document.querySelector(config.widget.toggleButtonSelector)\n : null;\n this.widgetResetSizeButtonElement = config.widget.resetSizeButtonSelector\n ? document.querySelector(config.widget.resetSizeButtonSelector)\n : null;\n this.widgetDefaultWidth = parsePixelValue(config.widget.defaultWidth) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).width) ||\n 380;\n this.widgetDefaultHeight = parsePixelValue(config.widget.defaultHeight) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).height) ||\n 520;\n this.widgetIsInitialized = true;\n\n if (config.widget.enableResizing) {\n chatWidgetContainer.classList.add('ai-chat-widget-resizable');\n chatWidgetContainer.style.minWidth = (parsePixelValue(config.widget.minWidth) || 320) + 'px';\n chatWidgetContainer.style.minHeight = (parsePixelValue(config.widget.minHeight) || 420) + 'px';\n\n if (typeof ResizeObserver !== 'undefined') {\n this.widgetResizeObserver = new ResizeObserver(() => {\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n });\n\n this.widgetResizeObserver.observe(chatWidgetContainer);\n }\n }\n\n var dragHandleSelector = config.widget.dragHandleSelector || '.ai-chat-widget-header';\n var dragHandle = chatWidgetContainer.querySelector(dragHandleSelector);\n\n if (config.widget.enableDragging && dragHandle) {\n dragHandle.classList.add('ai-chat-widget-drag-handle');\n chatWidgetContainer.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(chatWidgetContainer, dragHandle, 'panel', false);\n }\n\n if (config.widget.enableDragging && this.widgetToggleButtonElement) {\n this.widgetToggleButtonElement.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(this.widgetToggleButtonElement, this.widgetToggleButtonElement, 'toggle', true);\n }\n\n if (this.widgetResetSizeButtonElement) {\n this.widgetResetSizeButtonElement.addEventListener('click', (event) => {\n event.preventDefault();\n this.resetWidgetSize();\n });\n }\n\n this.restoreWidgetLayout();\n\n if (!this.widgetViewportResizeHandler) {\n this.widgetViewportResizeHandler = () => {\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n };\n\n window.addEventListener('resize', this.widgetViewportResizeHandler);\n }\n\n // Auto-load the last session so the user always sees previous chat history.\n this.reloadCurrentSession();\n\n if (config.autoCreateSession && !this.getSessionId()) {\n this.startNewSession();\n }\n\n if (config.widget.showHistoryButton && this.chatHistorySection) {\n\n const showHistoryButton = document.querySelector(config.widget.showHistoryButton);\n\n if (showHistoryButton) {\n showHistoryButton.addEventListener('click', () => {\n this.chatHistorySection.classList.toggle('show');\n });\n }\n\n if (config.widget.closeHistoryButton) {\n var closeHistoryButton = document.querySelector(config.widget.closeHistoryButton);\n\n if (closeHistoryButton) {\n closeHistoryButton.addEventListener('click', () => {\n this.showChatScreen();\n });\n }\n }\n }\n\n if (config.widget.newChatButton) {\n const newChatButton = document.querySelector(config.widget.newChatButton);\n\n if (newChatButton) {\n newChatButton.addEventListener('click', () => {\n this.resetSession();\n this.showChatScreen();\n });\n }\n }\n },\n showChatScreen() {\n\n if (!this.chatHistorySection) {\n return;\n }\n\n this.chatHistorySection.classList.remove('show');\n },\n getSessionId() {\n let sessionId = this.inputElement.getAttribute('data-session-id');\n\n if (!sessionId && this.widgetIsInitialized) {\n sessionId = localStorage.getItem(this.chatWidgetStateSession);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n navigator.clipboard.writeText(message);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Font Awesome SVG+JS replaces with , so we must replace\n // the entire button content and let Font Awesome re-process.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('i');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('i');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n\n // Trigger Font Awesome SVG+JS to convert the new elements.\n if (window.FontAwesome && FontAwesome.dom && FontAwesome.dom.i2svg) {\n FontAwesome.dom.i2svg({ node: container });\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() { this.renderDocumentBar(); },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n if (hasWidgetConfig) {\n this.initializeWidget();\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} +{"version":3,"sources":["ai-chat.js"],"names":["_regenerator","e","t","r","Symbol","n","iterator","o","toStringTag","i","c","prototype","Generator","u","Object","create","_regeneratorDefine2","f","p","y","G","v","a","d","bind","length","l","TypeError","call","done","value","GeneratorFunction","GeneratorFunctionPrototype","getPrototypeOf","this","setPrototypeOf","__proto__","displayName","w","m","defineProperty","_invoke","enumerable","configurable","writable","asyncGeneratorStep","Promise","resolve","then","_asyncToGenerator","arguments","apply","_next","_throw","_createForOfIteratorHelper","Array","isArray","_unsupportedIterableToArray","_n","F","s","next","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_nonIterableSpread","from","_arrayLikeToArray","_slicedToArray","_arrayWithHoles","_iterableToArrayLimit","_nonIterableRest","toString","slice","constructor","name","test","push","_typeof","window","openAIChatManager","defaultConfig","generatedImageAltText","generatedImageMaxWidth","downloadImageTitle","downloadChartTitle","downloadChartButtonText","userLabel","assistantLabel","thumbsUpTitle","thumbsDownTitle","copyTitle","codeCopiedText","widget","chatWidgetContainer","chatWidgetStateName","chatHistorySection","showHistoryButton","closeHistoryButton","newChatButton","toggleButtonSelector","resetSizeButtonSelector","dragHandleSelector","enableDragging","enableResizing","persistLayout","defaultWidth","defaultHeight","minWidth","minHeight","messageTemplate","indicatorTemplate","sanitizeUrl","url","trimmed","trim","escapeHtmlEntities","text","span","document","createElement","textContent","innerHTML","parsePixelValue","Number","isFinite","parsed","parseFloat","clamp","min","max","Math","normalizeReference","reference","_ref","_normalized$index","_ref2","_normalized$text","_ref3","_normalized$link","normalized","assign","index","Index","Text","link","Link","normalizeReferences","references","_i","_Object$entries","entries","_normalizeReference","_Object$entries$_i","key","renderer","marked","Renderer","data","href","concat","code","lang","highlighted","hljs","getLanguage","highlight","language","_","highlightAuto","langDisplay","image","src","alt","maxWidth","chartCounter","_pendingCharts","renderChartsInMessage","message","charts","requestAnimationFrame","_step","_iterator","renderChartOnCanvas","chartId","config","err","canvas","getElementById","Chart","console","warn","offsetParent","__chartConfigs","_cfg$options","_cfg$options2","_cfg$options2$aspectR","_chartInstance","destroy","cfg","JSON","parse","options","responsive","maintainAspectRatio","aspectRatio","error","parseMarkdownContent","content","html","DOMPurify","sanitize","ADD_TAGS","ADD_ATTR","use","extensions","level","start","idx","indexOf","undefined","tokenizer","extracted","token","jsonStart","depth","inString","escape","ch","jsonEnd","closeBracketIndex","startIndex","endIndex","json","substring","tryExtractChartMarker","type","raw","renderPendingCharts","configs","_i2","_Object$keys","keys","initialize","instanceConfig","hasWidgetConfig","signalRHubUrl","appElementSelector","chatContainerElementSelector","inputElementSelector","sendButtonElementSelector","app","Vue","createApp","inputElement","buttonElement","chatContainer","placeholder","isSessionStarted","isPlaceholderVisible","chatWidgetStateSession","chatWidgetLayoutKey","widgetContainerElement","widgetToggleButtonElement","widgetResetSizeButtonElement","widgetResizeObserver","widgetViewportResizeHandler","widgetDefaultWidth","widgetDefaultHeight","widgetIsInitialized","isStreaming","isNavigatingAway","autoScroll","stream","messages","notifications","prompt","documents","existingDocuments","isUploading","uploadErrors","isDragOver","documentBar","metricsEnabled","isRecording","mediaRecorder","preRecordingPrompt","micButton","speechToTextEnabled","chatMode","textToSpeechEnabled","ttsVoiceName","audioChunks","audioPlayQueue","isPlayingAudio","currentAudioElement","currentAudioUrl","ttsButton","ttsPlayingMessageIndex","ttsAudioCache","ttsInstanceId","random","singleResponseMode","conversationModeEnabled","conversationButton","isConversationMode","notificationDismissTimers","computed","lastAssistantIndex","role","methods","handleBeforeUnload","getStoredWidgetLayout","storedLayout","localStorage","getItem","saveStoredWidgetLayout","partialLayout","currentLayout","nextLayout","panel","position","setItem","stringify","getElementSize","element","fallbackWidth","fallbackHeight","width","height","rect","getBoundingClientRect","getComputedStyle","round","getElementPosition","left","top","inlineLeft","style","inlineTop","computedLeft","computedTop","isHidden","display","clampWidgetPosition","maxLeft","innerWidth","maxTop","innerHeight","applyAbsolutePosition","right","bottom","getWidgetDefaultSize","getWidgetToggleGap","isWidgetPanelVisible","classList","contains","persistWidgetPanelPosition","panelDefaultSize","panelPosition","panelSize","toggleSize","linkedPosition","persistWidgetTogglePosition","persistWidgetPanelSize","defaultSize","currentSize","abs","syncTogglePositionToPanel","syncPanelPositionToToggle","togglePosition","updateWidgetResetSizeButtonVisibility","isResized","toggle","add","resetWidgetSize","removeProperty","constrainWidgetElementsToViewport","restoreWidgetLayout","attachDraggableWidgetElement","handle","layoutKey","suppressClickOnDrag","_this","activePointerId","startX","startY","startLeft","startTop","dragged","stopDragging","event","pointerId","removeEventListener","onPointerMove","remove","dataset","dragSuppressClick","setTimeout","deltaX","clientX","deltaY","clientY","hypot","nextPosition","addEventListener","button","target","closest","setPointerCapture","preventDefault","clampedPanel","clampedToggle","handleDragOver","sessionDocumentsEnabled","stopPropagation","inputArea","handleDragLeave","handleDrop","dataTransfer","files","uploadFiles","triggerFileInput","fileInput","click","handleFileInputChange","_this2","_callee","sessionId","profileId","formData","response","errorText","uploadError","result","j","_t","_context","uploadDocumentUrl","getSessionId","getProfileId","renderDocumentBar","FormData","append","fetch","method","body","ok","extractReadableErrorMessage","fileName","initializeSession","uploaded","failed","removeDocument","doc","_this3","_callee2","removeError","_t2","_context2","removeDocumentUrl","headers","itemId","documentId","splice","status","formatFileSize","bytes","toFixed","escapeHtml","failedItem","failedName","errorMsg","supportedExtensionsText","replaceChildren","RETURN_DOM_FRAGMENT","self","closeButtons","querySelectorAll","docToRemove","parseInt","getAttribute","errorCloseButtons","addBtn","querySelector","div","fallbackMessage","startsWith","title","detail","normalizeAssistantAppearance","appearance","label","icon","cssClass","disableStreamingAnimation","getAssistantLabel","getAssistantRoleClasses","classes","getAssistantIconClasses","shouldAnimateAssistantIcon","getAssistantIcon","startConnection","_this4","_callee3","_t3","_context3","connection","signalR","HubConnectionBuilder","withUrl","withAutomaticReconnect","build","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","on","_data$messages","forEach","msg","addMessage","$nextTick","refreshAllFeedbackIcons","initialPrompt","sendMessage","stopRecording","_attemptedSessionRecovery","removeItem","startNewSession","messageId","userRating","find","id","isFinal","_conversationPartialTranscript","replace","_conversationPartialMessage","htmlContent","hidePlaceholder","isPartial","scrollToBottom","_audioInputSent","dispatchEvent","Event","stopAudio","_conversationAssistantMessage","oldMsg","escaped","responseId","hideTypingIndicator","msgIndex","newMessage","base64Audio","contentType","binaryString","atob","Uint8Array","charCodeAt","playCollectedAudio","notification","receiveNotification","updateNotification","notificationType","removeNotification","onreconnecting","onreconnected","info","reloadCurrentSession","autoCreateSession","onclose","addMessageInternal","_this5","fireEvent","CustomEvent","_this6","processedContent","citedRefs","filter","_ref4","includes","sort","_ref6","_ref7","b","_step2","displayIndex","_iterator2","_step2$value","replaceAll","_displayIndex","_placeholder","_step3","_iterator3","_step4","_iterator4","_step4$value","addMessages","_this7","showPlaceholder","isOrchestratorAvailable","applyOrchestratorAvailability","unavailableMessage","orchestratorUnavailableMessage","disabled","micButtonElement","conversationButtonElement","isIndicator","trimmedPrompt","streamMessage","startRecording","_this8","navigator","mediaDevices","getUserMedia","audio","echoCancellation","noiseSuppression","autoGainControl","mimeType","MediaRecorder","isTypeSupported","audioBitsPerSecond","subject","Subject","pendingChunk","size","_callee4","uint8Array","base64","_context4","arrayBuffer","reduce","str","byte","String","fromCharCode","btoa","getTracks","track","stop","complete","documentElement","send","updateMicButton","toggleRecording","sessionProfileId","_this9","dispose","streamingStarted","showTypingIndicator","lastResponseId","messageIndex","currentSessionId","subscribe","chunk","_i3","_Object$entries2","_normalizeReference2","_Object$entries2$_i","_i4","_Object$entries3","_Object$entries3$_i","_this9$stream","processReferences","streamingFinished","synthesizeSpeech","_this9$stream2","getServiceDownMessage","_this0","_ref1","_ref10","_ref11","_ref12","_step5","processed","_iterator5","_step5$value","_step6","_iterator6","_step7","_iterator7","_step7$value","stopIcon","setAttribute","startIcon","removeAttribute","focus","icons","handleExternalTtsStop","_e$detail","sourceId","cacheIndex","_this1","_ttsCacheIndex","invoke","toggleMessageTts","playAudioBlob","_step8","totalLength","sum","combined","offset","_iterator8","set","blob","Blob","_this10","URL","createObjectURL","Audio","revokeObjectURL","playNextInQueue","play","nextBlob","shift","conversationModeOnAudioEnded","pause","currentTime","toggleConversationMode","stopConversationMode","startConversationMode","_this11","updateConversationButton","_conversationSubject","_conversationStream","AudioCtx","AudioContext","webkitAudioContext","_conversationAudioCtx","_conversationAnalyser","createAnalyser","fftSize","createMediaStreamSource","connect","analyser","freqData","frequencyBinCount","getByteFrequencyData","k","_callee5","_context5","close","dismissible","autoDismissMs","endHtml","blur","startHtml","conversationModeSendPrompt","generatePrompt","templateProfileId","createSessionUrl","baseUrl","param","fullUrl","toLowerCase","location","origin","searchParams","originalLength","_this12","clearNotificationDismiss","existingIndex","findIndex","scheduleNotificationDismiss","_this13","timerId","clearTimeout","dismissNotification","handleNotificationAction","actionName","_this14","scrollTop","scrollHeight","clientHeight","handleUserInput","setSessionId","resetSession","sessionRating","initializeApp","_this15","placeholderElementSelector","loadSession","documentBarSelector","className","multiple","allowedExtensions","accept","parentElement","appendChild","atBottom","shiftKey","lastMsg","pop","promptGenerators","getElementsByClassName","chatSessions","showChatScreen","btn","block","codeEl","clipboard","writeText","copiedText","micButtonElementSelector","conversationButtonElementSelector","force","initializeWidget","_this16","ResizeObserver","observe","dragHandle","copyResponse","updateFeedbackIcons","container","upBtn","downBtn","upClass","upIcon","fontSize","downClass","downIcon","FontAwesome","dom","i2svg","node","containers","$el","msgId","rateMessage","isPositive","newRating","feedbackContainer","btnClass","offsetWidth","onEnd","watch","handler","deep","active","mounted","_this17","_callee6","_context6","beforeUnmount","template","mount","download","toDataURL","img","res","removeChild"],"mappings":"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","file":"ai-chat.min.js","sourcesContent":["window.openAIChatManager = function () {\n\n // Defaults (can be overridden by instanceConfig)\n var defaultConfig = {\n // UI defaults for generated media\n generatedImageAltText: 'Generated Image',\n generatedImageMaxWidth: 400,\n downloadImageTitle: 'Download image',\n downloadChartTitle: 'Download chart as image',\n downloadChartButtonText: 'Download',\n userLabel: 'You',\n assistantLabel: 'Assistant',\n thumbsUpTitle: 'Thumbs up',\n thumbsDownTitle: 'Thumbs down',\n copyTitle: 'Click here to copy response to clipboard.',\n codeCopiedText: 'Copied!',\n widget: {\n chatWidgetContainer: null,\n chatWidgetStateName: null,\n chatHistorySection: null,\n showHistoryButton: null,\n closeHistoryButton: null,\n newChatButton: null,\n toggleButtonSelector: null,\n resetSizeButtonSelector: null,\n dragHandleSelector: '.ai-chat-widget-header',\n enableDragging: true,\n enableResizing: true,\n persistLayout: true,\n defaultWidth: null,\n defaultHeight: null,\n minWidth: 320,\n minHeight: 420\n },\n messageTemplate: `\n
\n
\n
\n
{{ userLabel }}
\n
\n \n {{ getAssistantLabel(message) }}\n
\n
\n

{{ message.title }}

\n
\n \n \n \n \n \n
\n
\n
\n
\n
\n \n {{ notification.content }}\n \n
\n
\n \n
\n
\n
\n `,\n indicatorTemplate: `\n
\n \n Assistant\n
\n `\n };\n\n // Sanitize URLs to prevent javascript: protocol injection.\n function sanitizeUrl(url) {\n if (!url) return '';\n var trimmed = url.trim();\n if (/^javascript:/i.test(trimmed) || /^vbscript:/i.test(trimmed) || /^data:text\\/html/i.test(trimmed)) {\n return '';\n }\n return url;\n }\n\n // Safely HTML-encode a string using the DOM (avoids regex-based HTML filtering).\n function escapeHtmlEntities(text) {\n var span = document.createElement('span');\n span.textContent = text;\n return span.innerHTML;\n }\n\n function parsePixelValue(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n var parsed = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n\n function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n }\n\n function normalizeReference(reference) {\n if (!reference || typeof reference !== 'object') {\n return null;\n }\n\n const normalized = Object.assign({}, reference);\n normalized.index = normalized.index ?? normalized.Index ?? 0;\n normalized.text = normalized.text ?? normalized.Text ?? null;\n normalized.link = normalized.link ?? normalized.Link ?? null;\n\n return normalized;\n }\n\n function normalizeReferences(references) {\n if (!references || typeof references !== 'object') {\n return {};\n }\n\n const normalized = {};\n\n for (const [key, value] of Object.entries(references)) {\n normalized[key] = normalizeReference(value) ?? {};\n }\n\n return normalized;\n }\n\n const renderer = new marked.Renderer();\n\n // Modify the link rendering to open in a new tab\n renderer.link = function (data) {\n var href = sanitizeUrl(data.href);\n if (!href) return data.text || '';\n return `
${data.text}`;\n };\n\n // Custom code block renderer with highlight.js integration and copy button.\n renderer.code = function (data) {\n var code = data.text || '';\n var lang = (data.lang || '').trim();\n var highlighted = code;\n\n if (typeof hljs !== 'undefined') {\n if (lang && hljs.getLanguage(lang)) {\n try {\n highlighted = hljs.highlight(code, { language: lang }).value;\n } catch (_) { }\n } else {\n try {\n highlighted = hljs.highlightAuto(code).value;\n } catch (_) { }\n }\n } else {\n highlighted = escapeHtmlEntities(code);\n }\n\n var langDisplay = lang ? escapeHtmlEntities(lang) : 'code';\n return `
${langDisplay}
${highlighted}
`;\n };\n\n // Custom image renderer for generated images with thumbnail styling and download button.\n // Handles both URL and data-URI sources (data URIs are converted to blobs for download).\n renderer.image = function (data) {\n const src = sanitizeUrl(data.href);\n if (!src) return '';\n const alt = data.text || defaultConfig.generatedImageAltText;\n const maxWidth = defaultConfig.generatedImageMaxWidth;\n return `
\n \"${alt}\"\n
\n \n \n \n
\n
`;\n };\n\n // Chart counter for unique IDs\n let chartCounter = 0;\n\n // Collector for charts discovered during marked parsing.\n let _pendingCharts = [];\n\n // Global chart config map: any page (e.g., Chat Interactions) that uses\n // the shared marked instance can call window.renderPendingCharts() after\n // its DOM update to render charts it didn't create itself.\n window.__chartConfigs = window.__chartConfigs || {};\n\n function createChartHtml(chartId) {\n return `
`\n + ``\n + `
`\n + `
`\n + ``\n + `
`;\n }\n\n // Register [chart:{...json...}] as a native marked block extension so the\n // markdown parser handles chart markers inline with surrounding text.\n marked.use({\n extensions: [{\n name: 'chart',\n level: 'block',\n start(src) {\n const idx = src.indexOf('[chart:');\n return idx >= 0 ? idx : undefined;\n },\n tokenizer(src) {\n const extracted = tryExtractChartMarker(src);\n if (!extracted || extracted.startIndex !== 0) {\n return undefined;\n }\n\n const chartId = `chat_chart_${++chartCounter}`;\n\n return {\n type: 'chart',\n raw: src.substring(0, extracted.endIndex),\n chartId: chartId,\n json: extracted.json,\n };\n },\n renderer(token) {\n _pendingCharts.push({ chartId: token.chartId, config: token.json });\n window.__chartConfigs[token.chartId] = token.json;\n return createChartHtml(token.chartId);\n }\n }]\n });\n\n // Extract a [chart:{...json...}] marker. This avoids regex issues with nested brackets.\n function tryExtractChartMarker(text) {\n const token = '[chart:';\n const start = text.indexOf(token);\n if (start < 0) {\n return null;\n }\n\n // Find JSON object boundary by balancing braces\n const jsonStart = start + token.length;\n let i = jsonStart;\n while (i < text.length && (text[i] === ' ' || text[i] === '\\n' || text[i] === '\\r' || text[i] === '\\t')) {\n i++;\n }\n\n if (i >= text.length || text[i] !== '{') {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (; i < text.length; i++) {\n const ch = text[i];\n\n if (inString) {\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === '{') {\n depth++;\n } else if (ch === '}') {\n depth--;\n if (depth === 0) {\n const jsonEnd = i;\n // Expect closing bracket after JSON\n const closeBracketIndex = text.indexOf(']', jsonEnd + 1);\n if (closeBracketIndex < 0) {\n return null;\n }\n\n const json = text.substring(jsonStart, jsonEnd + 1).trim();\n return {\n startIndex: start,\n endIndex: closeBracketIndex + 1,\n json: json\n };\n }\n }\n }\n\n return null;\n }\n\n function renderChartsInMessage(message) {\n if (!message || !message._pendingCharts || !message._pendingCharts.length) {\n return;\n }\n\n // Copy and clear pending charts immediately to prevent duplicate renders.\n const charts = [...message._pendingCharts];\n message._pendingCharts = [];\n\n // Defer to requestAnimationFrame so the browser has fully laid out the\n // canvas elements before Chart.js reads their dimensions.\n requestAnimationFrame(() => {\n for (const c of charts) {\n renderChartOnCanvas(c.chartId, c.config);\n }\n });\n }\n\n function renderChartOnCanvas(chartId, config) {\n const canvas = document.getElementById(chartId);\n if (!canvas) {\n return false;\n }\n\n if (typeof Chart === 'undefined') {\n console.warn('Chart.js is not loaded. To render interactive charts, include the Chart.js library on the page (e.g., ).');\n return false;\n }\n\n // When the canvas is inside a hidden container (e.g., a widget panel with\n // display:none), it has zero dimensions and Chart.js cannot render correctly.\n // Keep the config in __chartConfigs so renderPendingCharts() can retry later\n // once the container becomes visible.\n if (canvas.offsetParent === null) {\n window.__chartConfigs[chartId] = config;\n return false;\n }\n\n try {\n if (canvas._chartInstance) {\n canvas._chartInstance.destroy();\n }\n\n const cfg = typeof config === 'string' ? JSON.parse(config) : config;\n cfg.options ??= {};\n cfg.options.responsive = true;\n cfg.options.maintainAspectRatio = true;\n cfg.options.aspectRatio ??= 4 / 3;\n\n canvas._chartInstance = new Chart(canvas, cfg);\n delete window.__chartConfigs[chartId];\n return true;\n } catch (e) {\n console.error('Error creating chart:', e);\n return false;\n }\n }\n\n // Global function: renders any chart canvases whose configs are in the\n // global __chartConfigs map. Called by pages (e.g., Chat Interactions)\n // that share the marked instance but have their own rendering pipeline.\n window.renderPendingCharts = function () {\n if (typeof Chart === 'undefined') {\n return;\n }\n\n const configs = window.__chartConfigs;\n if (!configs) {\n return;\n }\n\n requestAnimationFrame(() => {\n for (const chartId of Object.keys(configs)) {\n renderChartOnCanvas(chartId, configs[chartId]);\n }\n });\n };\n\n // Parse markdown content via marked (which natively handles [chart:...] markers\n // through the registered extension) and collect pending chart configs for later\n // Chart.js rendering.\n function parseMarkdownContent(content, message) {\n _pendingCharts = [];\n const html = marked.parse(content, { renderer });\n message._pendingCharts = _pendingCharts.length > 0 ? [..._pendingCharts] : [];\n return DOMPurify.sanitize(html, { ADD_TAGS: ['canvas'], ADD_ATTR: ['target'] });\n }\n\n const initialize = (instanceConfig) => {\n\n const config = Object.assign({}, defaultConfig, instanceConfig);\n config.widget = Object.assign({}, defaultConfig.widget || {}, instanceConfig && instanceConfig.widget ? instanceConfig.widget : {});\n const hasWidgetConfig = !!(instanceConfig && instanceConfig.widget && instanceConfig.widget.chatWidgetContainer && instanceConfig.widget.chatWidgetStateName);\n // Keep defaultConfig in sync so renderers use overridden values\n defaultConfig = config;\n\n if (!config.signalRHubUrl) {\n console.error('The signalRHubUrl is required.');\n return;\n }\n\n if (!config.appElementSelector) {\n console.error('The appElementSelector is required.');\n return;\n }\n\n if (!config.chatContainerElementSelector) {\n console.error('The chatContainerElementSelector is required.');\n return;\n }\n\n if (!config.inputElementSelector) {\n console.error('The inputElementSelector is required.');\n return;\n }\n\n if (!config.sendButtonElementSelector) {\n console.error('The sendButtonElementSelector is required.');\n return;\n }\n\n const app = Vue.createApp({\n data() {\n return {\n inputElement: null,\n buttonElement: null,\n chatContainer: null,\n placeholder: null,\n isSessionStarted: false,\n isPlaceholderVisible: true,\n chatWidgetStateName: null,\n chatWidgetStateSession: null,\n chatWidgetLayoutKey: null,\n chatHistorySection: null,\n widgetContainerElement: null,\n widgetToggleButtonElement: null,\n widgetResetSizeButtonElement: null,\n widgetResizeObserver: null,\n widgetViewportResizeHandler: null,\n widgetDefaultWidth: null,\n widgetDefaultHeight: null,\n widgetIsInitialized: false,\n isStreaming: false,\n isNavigatingAway: false,\n autoScroll: true,\n stream: null,\n messages: [],\n notifications: [],\n prompt: '',\n documents: config.existingDocuments || [],\n isUploading: false,\n uploadErrors: [],\n isDragOver: false,\n documentBar: null,\n metricsEnabled: !!config.metricsEnabled,\n userLabel: config.userLabel,\n assistantLabel: config.assistantLabel,\n thumbsUpTitle: config.thumbsUpTitle,\n thumbsDownTitle: config.thumbsDownTitle,\n copyTitle: config.copyTitle,\n isRecording: false,\n mediaRecorder: null,\n preRecordingPrompt: '',\n micButton: null,\n speechToTextEnabled: config.chatMode === 'AudioInput' || config.chatMode === 'Conversation',\n textToSpeechEnabled: config.chatMode === 'Conversation' || !!config.textToSpeechEnabled,\n ttsVoiceName: config.ttsVoiceName || null,\n audioChunks: [],\n audioPlayQueue: [],\n isPlayingAudio: false,\n currentAudioElement: null,\n currentAudioUrl: null,\n ttsButton: null,\n ttsPlayingMessageIndex: -1,\n ttsAudioCache: {},\n ttsInstanceId: 'ai-chat-' + Math.random().toString(36).slice(2),\n singleResponseMode: !!config.singleResponseMode,\n conversationModeEnabled: config.chatMode === 'Conversation',\n conversationButton: null,\n isConversationMode: false,\n notificationDismissTimers: {},\n };\n },\n computed: {\n lastAssistantIndex() {\n for (var i = this.messages.length - 1; i >= 0; i--) {\n if (this.messages[i].role === 'assistant') {\n return i;\n }\n }\n return -1;\n }\n },\n methods: {\n handleBeforeUnload() {\n this.isNavigatingAway = true;\n },\n getStoredWidgetLayout() {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return {};\n }\n\n try {\n var storedLayout = localStorage.getItem(this.chatWidgetLayoutKey);\n return storedLayout ? JSON.parse(storedLayout) || {} : {};\n } catch (error) {\n console.warn('Failed to read widget layout state.', error);\n return {};\n }\n },\n saveStoredWidgetLayout(partialLayout) {\n if (!this.chatWidgetLayoutKey || !config.widget.persistLayout) {\n return;\n }\n\n var currentLayout = this.getStoredWidgetLayout();\n var nextLayout = Object.assign({}, currentLayout);\n\n if (partialLayout.panel !== undefined) {\n nextLayout.panel = Object.assign({}, currentLayout.panel || {}, partialLayout.panel || {});\n }\n\n if (partialLayout.position !== undefined) {\n nextLayout.position = Object.assign({}, currentLayout.position || {}, partialLayout.position || {});\n }\n\n localStorage.setItem(this.chatWidgetLayoutKey, JSON.stringify(nextLayout));\n },\n getElementSize(element, fallbackWidth, fallbackHeight) {\n if (!element) {\n return {\n width: fallbackWidth || 0,\n height: fallbackHeight || 0\n };\n }\n\n var rect = element.getBoundingClientRect();\n var computed = window.getComputedStyle(element);\n\n return {\n width: Math.round(rect.width || parsePixelValue(computed.width) || fallbackWidth || 0),\n height: Math.round(rect.height || parsePixelValue(computed.height) || fallbackHeight || 0)\n };\n },\n getElementPosition(element) {\n if (!element) {\n return {\n left: 0,\n top: 0\n };\n }\n\n var rect = element.getBoundingClientRect();\n var computed = window.getComputedStyle(element);\n var inlineLeft = parsePixelValue(element.style.left);\n var inlineTop = parsePixelValue(element.style.top);\n var computedLeft = parsePixelValue(computed.left);\n var computedTop = parsePixelValue(computed.top);\n var isHidden = computed.display === 'none';\n\n return {\n left: Math.round(\n isHidden && Number.isFinite(inlineLeft)\n ? inlineLeft\n : rect.left || inlineLeft || computedLeft || 0),\n top: Math.round(\n isHidden && Number.isFinite(inlineTop)\n ? inlineTop\n : rect.top || inlineTop || computedTop || 0)\n };\n },\n clampWidgetPosition(left, top, width, height) {\n var viewportPadding = 8;\n var maxLeft = Math.max(viewportPadding, window.innerWidth - width - viewportPadding);\n var maxTop = Math.max(viewportPadding, window.innerHeight - height - viewportPadding);\n\n return {\n left: Math.round(clamp(left, viewportPadding, maxLeft)),\n top: Math.round(clamp(top, viewportPadding, maxTop))\n };\n },\n applyAbsolutePosition(element, left, top) {\n if (!element) {\n return;\n }\n\n element.style.left = left + 'px';\n element.style.top = top + 'px';\n element.style.right = 'auto';\n element.style.bottom = 'auto';\n },\n getWidgetDefaultSize() {\n return {\n width: this.widgetDefaultWidth || parsePixelValue(config.widget.defaultWidth) || 380,\n height: this.widgetDefaultHeight || parsePixelValue(config.widget.defaultHeight) || 520\n };\n },\n getWidgetToggleGap() {\n return 8;\n },\n isWidgetPanelVisible() {\n if (!this.widgetContainerElement) {\n return false;\n }\n\n var computed = window.getComputedStyle(this.widgetContainerElement);\n return this.widgetContainerElement.classList.contains('open') && computed.display !== 'none';\n },\n persistWidgetPanelPosition() {\n if (!this.widgetContainerElement || !config.widget.persistLayout) {\n return;\n }\n\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelPosition = this.getElementPosition(this.widgetContainerElement);\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var linkedPosition = this.clampWidgetPosition(\n panelPosition.left + panelSize.width - toggleSize.width,\n panelPosition.top + panelSize.height + this.getWidgetToggleGap(),\n toggleSize.width,\n toggleSize.height);\n\n this.saveStoredWidgetLayout({\n position: {\n left: linkedPosition.left,\n top: linkedPosition.top\n }\n });\n },\n persistWidgetTogglePosition() {\n if (!this.widgetToggleButtonElement || !config.widget.persistLayout) {\n return;\n }\n\n var toggleRect = this.widgetToggleButtonElement.getBoundingClientRect();\n this.saveStoredWidgetLayout({\n position: {\n left: this.getElementPosition(this.widgetToggleButtonElement).left,\n top: this.getElementPosition(this.widgetToggleButtonElement).top\n }\n });\n },\n persistWidgetPanelSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing || !config.widget.persistLayout) {\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n\n this.saveStoredWidgetLayout({\n panel: {\n width: Math.abs(currentSize.width - defaultSize.width) <= 1 ? null : currentSize.width,\n height: Math.abs(currentSize.height - defaultSize.height) <= 1 ? null : currentSize.height\n }\n });\n },\n syncTogglePositionToPanel(persistLayout = true) {\n if (!this.widgetContainerElement || !this.widgetToggleButtonElement) {\n return;\n }\n\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var panelPosition = this.getElementPosition(this.widgetContainerElement);\n var linkedPosition = this.clampWidgetPosition(\n panelPosition.left + panelSize.width - toggleSize.width,\n panelPosition.top + panelSize.height + this.getWidgetToggleGap(),\n toggleSize.width,\n toggleSize.height);\n\n this.applyAbsolutePosition(this.widgetToggleButtonElement, linkedPosition.left, linkedPosition.top);\n\n if (persistLayout && config.widget.persistLayout) {\n this.persistWidgetTogglePosition();\n }\n },\n syncPanelPositionToToggle(persistLayout = true) {\n if (!this.widgetContainerElement || !this.widgetToggleButtonElement) {\n return;\n }\n\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var togglePosition = this.getElementPosition(this.widgetToggleButtonElement);\n var linkedPosition = this.clampWidgetPosition(\n togglePosition.left + toggleSize.width - panelSize.width,\n togglePosition.top - panelSize.height - this.getWidgetToggleGap(),\n panelSize.width,\n panelSize.height);\n\n this.applyAbsolutePosition(this.widgetContainerElement, linkedPosition.left, linkedPosition.top);\n\n if (persistLayout && config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n }\n },\n updateWidgetResetSizeButtonVisibility() {\n if (!this.widgetResetSizeButtonElement) {\n return;\n }\n\n if (!config.widget.enableResizing || !this.widgetContainerElement) {\n this.widgetResetSizeButtonElement.classList.add('d-none');\n return;\n }\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(this.widgetContainerElement, defaultSize.width, defaultSize.height);\n var isResized =\n Math.abs(currentSize.width - defaultSize.width) > 1 ||\n Math.abs(currentSize.height - defaultSize.height) > 1 ||\n !!this.widgetContainerElement.style.width ||\n !!this.widgetContainerElement.style.height;\n\n this.widgetResetSizeButtonElement.classList.toggle('d-none', !isResized);\n },\n resetWidgetSize() {\n if (!this.widgetContainerElement || !config.widget.enableResizing) {\n return;\n }\n\n this.widgetContainerElement.style.removeProperty('width');\n this.widgetContainerElement.style.removeProperty('height');\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n restoreWidgetLayout() {\n var storedLayout = this.getStoredWidgetLayout();\n\n if (this.widgetContainerElement && config.widget.enableResizing) {\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.width)) {\n this.widgetContainerElement.style.width = storedLayout.panel.width + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('width');\n }\n\n if (Number.isFinite(storedLayout.panel && storedLayout.panel.height)) {\n this.widgetContainerElement.style.height = storedLayout.panel.height + 'px';\n } else {\n this.widgetContainerElement.style.removeProperty('height');\n }\n }\n\n if (this.widgetToggleButtonElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.position && storedLayout.position.left) &&\n Number.isFinite(storedLayout.position && storedLayout.position.top)) {\n this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.position.left, storedLayout.position.top);\n this.syncPanelPositionToToggle(false);\n } else if (this.widgetToggleButtonElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.left) &&\n Number.isFinite(storedLayout.toggle && storedLayout.toggle.top)) {\n this.applyAbsolutePosition(this.widgetToggleButtonElement, storedLayout.toggle.left, storedLayout.toggle.top);\n this.syncPanelPositionToToggle(false);\n } else if (this.widgetContainerElement && config.widget.enableDragging &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.left) &&\n Number.isFinite(storedLayout.panel && storedLayout.panel.top)) {\n this.applyAbsolutePosition(this.widgetContainerElement, storedLayout.panel.left, storedLayout.panel.top);\n this.syncTogglePositionToPanel(false);\n }\n\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n },\n attachDraggableWidgetElement(element, handle, layoutKey, suppressClickOnDrag) {\n if (!element || !handle || !config.widget.enableDragging) {\n return;\n }\n\n var activePointerId = null;\n var startX = 0;\n var startY = 0;\n var startLeft = 0;\n var startTop = 0;\n var dragged = false;\n var dragThreshold = 4;\n var interactiveSelector = 'button, a, input, textarea, select, option, label';\n\n var stopDragging = (event) => {\n if (activePointerId === null) {\n return;\n }\n\n if (event && event.pointerId !== undefined && event.pointerId !== activePointerId) {\n return;\n }\n\n document.removeEventListener('pointermove', onPointerMove);\n document.removeEventListener('pointerup', stopDragging);\n document.removeEventListener('pointercancel', stopDragging);\n element.classList.remove('ai-chat-widget-dragging');\n activePointerId = null;\n\n if (!dragged) {\n return;\n }\n\n if (layoutKey === 'panel') {\n this.syncTogglePositionToPanel(false);\n this.persistWidgetPanelPosition();\n } else if (layoutKey === 'toggle') {\n this.syncPanelPositionToToggle(false);\n this.persistWidgetTogglePosition();\n }\n\n if (config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n this.persistWidgetTogglePosition();\n }\n\n if (suppressClickOnDrag) {\n element.dataset.dragSuppressClick = 'true';\n window.setTimeout(() => {\n if (element.dataset.dragSuppressClick === 'true') {\n element.dataset.dragSuppressClick = 'false';\n }\n }, 0);\n }\n };\n\n var onPointerMove = (event) => {\n if (activePointerId === null || event.pointerId !== activePointerId) {\n return;\n }\n\n var deltaX = event.clientX - startX;\n var deltaY = event.clientY - startY;\n\n if (!dragged && Math.hypot(deltaX, deltaY) < dragThreshold) {\n return;\n }\n\n dragged = true;\n\n var defaultSize = this.getWidgetDefaultSize();\n var currentSize = this.getElementSize(\n element,\n layoutKey === 'panel' ? defaultSize.width : 52,\n layoutKey === 'panel' ? defaultSize.height : 52);\n var nextPosition = this.clampWidgetPosition(\n startLeft + deltaX,\n startTop + deltaY,\n currentSize.width,\n currentSize.height);\n\n this.applyAbsolutePosition(element, nextPosition.left, nextPosition.top);\n\n if (layoutKey === 'panel') {\n this.syncTogglePositionToPanel(false);\n } else if (layoutKey === 'toggle') {\n this.syncPanelPositionToToggle(false);\n }\n };\n\n handle.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) {\n return;\n }\n\n if (layoutKey === 'panel' && event.target.closest(interactiveSelector)) {\n return;\n }\n\n var rect = element.getBoundingClientRect();\n startX = event.clientX;\n startY = event.clientY;\n startLeft = rect.left;\n startTop = rect.top;\n dragged = false;\n activePointerId = event.pointerId;\n element.classList.add('ai-chat-widget-dragging');\n\n if (handle.setPointerCapture) {\n handle.setPointerCapture(event.pointerId);\n }\n\n document.addEventListener('pointermove', onPointerMove);\n document.addEventListener('pointerup', stopDragging);\n document.addEventListener('pointercancel', stopDragging);\n event.preventDefault();\n });\n },\n constrainWidgetElementsToViewport() {\n if (this.widgetContainerElement && this.widgetContainerElement.style.left && this.isWidgetPanelVisible()) {\n var panelDefaultSize = this.getWidgetDefaultSize();\n var panelSize = this.getElementSize(this.widgetContainerElement, panelDefaultSize.width, panelDefaultSize.height);\n var panelPosition = this.getElementPosition(this.widgetContainerElement);\n var clampedPanel = this.clampWidgetPosition(panelPosition.left, panelPosition.top, panelSize.width, panelSize.height);\n\n this.applyAbsolutePosition(this.widgetContainerElement, clampedPanel.left, clampedPanel.top);\n this.syncTogglePositionToPanel(false);\n\n if (config.widget.persistLayout) {\n this.persistWidgetPanelPosition();\n this.persistWidgetTogglePosition();\n }\n } else if (this.widgetToggleButtonElement && this.widgetToggleButtonElement.style.left) {\n var toggleSize = this.getElementSize(this.widgetToggleButtonElement, 52, 52);\n var togglePosition = this.getElementPosition(this.widgetToggleButtonElement);\n var clampedToggle = this.clampWidgetPosition(togglePosition.left, togglePosition.top, toggleSize.width, toggleSize.height);\n\n this.applyAbsolutePosition(this.widgetToggleButtonElement, clampedToggle.left, clampedToggle.top);\n this.syncPanelPositionToToggle(false);\n\n if (config.widget.persistLayout) {\n this.persistWidgetTogglePosition();\n this.persistWidgetPanelPosition();\n }\n }\n },\n handleDragOver(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = true;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.add('ai-chat-drag-over');\n },\n handleDragLeave(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n },\n handleDrop(e) {\n if (!config.sessionDocumentsEnabled) return;\n e.preventDefault();\n e.stopPropagation();\n this.isDragOver = false;\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) inputArea.classList.remove('ai-chat-drag-over');\n if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.uploadFiles(e.dataTransfer.files);\n }\n },\n triggerFileInput() {\n if (!config.sessionDocumentsEnabled) return;\n var fileInput = document.getElementById('ai-chat-doc-input');\n if (fileInput) fileInput.click();\n },\n handleFileInputChange(e) {\n var files = e.target.files;\n if (files && files.length > 0) {\n this.uploadFiles(files);\n }\n e.target.value = '';\n },\n async uploadFiles(files) {\n if (!config.uploadDocumentUrl) return;\n\n var sessionId = this.getSessionId();\n var profileId = this.getProfileId();\n\n if (!sessionId && !profileId) {\n console.warn('Cannot upload documents without a session or profile.');\n return;\n }\n\n this.isUploading = true;\n this.uploadErrors = [];\n this.renderDocumentBar();\n try {\n var formData = new FormData();\n if (sessionId) {\n formData.append('sessionId', sessionId);\n } else {\n formData.append('profileId', profileId);\n }\n for (var i = 0; i < files.length; i++) {\n formData.append('files', files[i]);\n }\n\n var response = await fetch(config.uploadDocumentUrl, {\n method: 'POST',\n body: formData\n });\n\n if (!response.ok) {\n var errorText = await response.text();\n var uploadError = this.extractReadableErrorMessage(errorText, 'Upload failed. Please try again.');\n console.error('Upload failed:', errorText);\n this.uploadErrors = [{ fileName: '', error: uploadError }];\n return;\n }\n\n var result = await response.json();\n\n // If the server created a new session, initialize it.\n if (result.sessionId && !sessionId) {\n this.initializeSession(result.sessionId);\n }\n\n if (result.uploaded && result.uploaded.length > 0) {\n for (var j = 0; j < result.uploaded.length; j++) {\n this.documents.push(result.uploaded[j]);\n }\n }\n if (result.failed && result.failed.length > 0) {\n this.uploadErrors = result.failed;\n }\n } catch (err) {\n console.error('Upload error:', err);\n this.uploadErrors = [{ fileName: '', error: 'Upload failed. Please try again.' }];\n } finally {\n this.isUploading = false;\n this.renderDocumentBar();\n }\n },\n async removeDocument(doc) {\n if (!config.removeDocumentUrl) return;\n\n try {\n var sessionId = this.getSessionId();\n var response = await fetch(config.removeDocumentUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ itemId: sessionId, documentId: doc.documentId })\n });\n\n if (response.ok) {\n var idx = this.documents.indexOf(doc);\n if (idx > -1) this.documents.splice(idx, 1);\n } else {\n var errorText = await response.text();\n var removeError = this.extractReadableErrorMessage(errorText, 'Failed to remove document. Please try again.');\n console.error('Failed to remove document:', response.status, errorText);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: removeError }];\n this.renderDocumentBar();\n }\n } catch (err) {\n console.error('Remove document error:', err);\n this.uploadErrors = [{ fileName: doc.fileName || '', error: 'Failed to remove document. Please try again.' }];\n this.renderDocumentBar();\n }\n },\n formatFileSize(bytes) {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n },\n renderDocumentBar() {\n if (!this.documentBar) return;\n\n if (!config.sessionDocumentsEnabled) {\n this.documentBar.classList.add('d-none');\n return;\n }\n\n this.documentBar.classList.remove('d-none');\n\n var html = '
';\n html += '
';\n\n for (var i = 0; i < this.documents.length; i++) {\n var doc = this.documents[i];\n var name = doc.fileName || 'Document';\n if (name.length > 20) name = name.substring(0, 17) + '...';\n html += '';\n html += ' ';\n html += this.escapeHtml(name);\n html += ' ';\n html += '';\n }\n\n for (var m = 0; m < this.uploadErrors.length; m++) {\n var failedItem = this.uploadErrors[m];\n var failedName = failedItem.fileName || 'File';\n var errorMsg = failedItem.error || 'Upload failed';\n if (failedName.length > 15) failedName = failedName.substring(0, 12) + '...';\n html += '';\n html += ' ';\n html += this.escapeHtml(failedName);\n html += ' ';\n html += '';\n }\n\n if (this.isUploading) {\n html += '';\n html += ' Uploading...';\n html += '';\n }\n\n html += '';\n html += '
';\n if (config.supportedExtensionsText) {\n html += '
Supported formats: ' + this.escapeHtml(config.supportedExtensionsText) + '
';\n }\n\n html += '
';\n\n this.documentBar.replaceChildren(DOMPurify.sanitize(html, { RETURN_DOM_FRAGMENT: true }));\n\n // Bind remove handlers\n var self = this;\n var closeButtons = this.documentBar.querySelectorAll('[data-doc-index]');\n for (var j = 0; j < closeButtons.length; j++) {\n closeButtons[j].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n var docToRemove = self.documents[idx];\n if (docToRemove) self.removeDocument(docToRemove);\n };\n })(parseInt(closeButtons[j].getAttribute('data-doc-index'))));\n }\n\n // Bind error dismiss handlers\n var errorCloseButtons = this.documentBar.querySelectorAll('[data-error-index]');\n for (var n = 0; n < errorCloseButtons.length; n++) {\n errorCloseButtons[n].addEventListener('click', (function (idx) {\n return function (e) {\n e.preventDefault();\n e.stopPropagation();\n self.uploadErrors.splice(idx, 1);\n self.renderDocumentBar();\n };\n })(parseInt(errorCloseButtons[n].getAttribute('data-error-index'))));\n }\n\n // Bind add button\n var addBtn = this.documentBar.querySelector('.ai-chat-doc-add-btn');\n if (addBtn) {\n addBtn.addEventListener('click', function (e) {\n e.preventDefault();\n self.triggerFileInput();\n });\n }\n },\n escapeHtml(text) {\n var div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n },\n extractReadableErrorMessage(errorText, fallbackMessage) {\n if (!errorText || typeof errorText !== 'string') {\n return fallbackMessage;\n }\n\n var trimmed = errorText.trim();\n if (!trimmed) {\n return fallbackMessage;\n }\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n var parsed = JSON.parse(trimmed);\n var message = parsed?.error || parsed?.message || parsed?.title || parsed?.detail;\n return typeof message === 'string' && message.trim()\n ? message.trim()\n : fallbackMessage;\n } catch (err) {\n return fallbackMessage;\n }\n }\n\n if (/<[^>]+>/.test(trimmed)) {\n return fallbackMessage;\n }\n\n return trimmed;\n },\n normalizeAssistantAppearance(appearance) {\n if (!appearance) {\n return null;\n }\n\n var label = typeof appearance.label === 'string' ? appearance.label.trim() : '';\n var icon = typeof appearance.icon === 'string' ? appearance.icon.trim() : '';\n var cssClass = typeof appearance.cssClass === 'string' ? appearance.cssClass.trim() : '';\n var disableStreamingAnimation = !!appearance.disableStreamingAnimation;\n\n if (!label && !icon && !cssClass && !disableStreamingAnimation) {\n return null;\n }\n\n return {\n label: label,\n icon: icon,\n cssClass: cssClass,\n disableStreamingAnimation: disableStreamingAnimation,\n };\n },\n getAssistantLabel(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.label ? appearance.label : this.assistantLabel;\n },\n getAssistantRoleClasses(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n var classes = ['ai-chat-msg-role'];\n\n if (appearance && appearance.cssClass) {\n classes.push(appearance.cssClass);\n } else {\n classes.push('ai-chat-msg-role-assistant');\n }\n\n return classes;\n },\n getAssistantIconClasses(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return [this.shouldAnimateAssistantIcon(message, index) ? 'ai-streaming-icon' : 'ai-bot-icon', appearance && appearance.cssClass ? appearance.cssClass : ''];\n },\n getAssistantIcon(message) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return appearance && appearance.icon ? appearance.icon : 'fa fa-robot';\n },\n shouldAnimateAssistantIcon(message, index) {\n var appearance = message ? this.normalizeAssistantAppearance(message.appearance) : null;\n return !!message &&\n message.isStreaming &&\n index === this.lastAssistantIndex &&\n !(appearance && appearance.disableStreamingAnimation);\n },\n async startConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(config.signalRHubUrl)\n .withAutomaticReconnect()\n .build();\n\n // Allow long-running operations (e.g., multi-step MCP tool calls)\n // without the client disconnecting prematurely.\n this.connection.serverTimeoutInMilliseconds = 600000;\n this.connection.keepAliveIntervalInMilliseconds = 15000;\n\n this.connection.on(\"LoadSession\", (data) => {\n this.initializeSession(data.sessionId, true);\n this.messages = [];\n this.documents = data.documents || [];\n\n (data.messages ?? []).forEach(msg => {\n this.addMessage(msg);\n\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n });\n });\n\n // Update feedback icons in the DOM after all messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // When the session is new (no messages) and an initial prompt is configured,\n // automatically send it as the first user message to trigger an AI response.\n if (this.messages.length === 0 && config.initialPrompt) {\n this.prompt = config.initialPrompt;\n this.sendMessage();\n }\n });\n\n this.connection.on(\"ReceiveError\", (error) => {\n console.error(\"SignalR Error: \", error);\n\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // If this is a widget with a stale cached session (e.g., profile was deleted),\n // clear the cached session and start fresh with the current profile.\n if (this.widgetIsInitialized && !this.isSessionStarted && !this._attemptedSessionRecovery) {\n this._attemptedSessionRecovery = true;\n localStorage.removeItem(this.chatWidgetStateSession);\n this.startNewSession();\n }\n });\n\n this.connection.on(\"MessageRated\", (messageId, userRating) => {\n var msg = this.messages.find(m => m.id === messageId);\n if (msg) {\n msg.userRating = userRating;\n }\n });\n\n this.connection.on(\"ReceiveTranscript\", (sessionId, text, isFinal) => {\n if (this.isConversationMode) {\n if (!isFinal && text) {\n this._conversationPartialTranscript = text;\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n var html = '

' + escaped + '

';\n\n // Show partial transcript as a live user message.\n if (!this._conversationPartialMessage) {\n this.hidePlaceholder();\n this._conversationPartialMessage = {\n role: 'user',\n content: text,\n htmlContent: html,\n isPartial: true\n };\n this.messages.push(this._conversationPartialMessage);\n } else {\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = html;\n }\n this.scrollToBottom();\n }\n return;\n }\n\n if (text && !this._audioInputSent) {\n this.prompt = this.preRecordingPrompt + text;\n if (this.inputElement) {\n this.inputElement.value = this.prompt;\n this.inputElement.dispatchEvent(new Event('input'));\n }\n }\n });\n\n this.connection.on(\"ReceiveConversationUserMessage\", (sessionId, text) => {\n if (text) {\n this.stopAudio();\n\n // If there's an interrupted assistant message still streaming,\n // mark it as done to stop the spinner animation.\n if (this._conversationAssistantMessage) {\n var oldMsg = this.messages[this._conversationAssistantMessage.index];\n if (oldMsg) {\n oldMsg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Replace the partial transcript message with the final one.\n if (this._conversationPartialMessage) {\n var escaped = text.replace(/&/g, '&').replace(//g, '>');\n this._conversationPartialMessage.content = text;\n this._conversationPartialMessage.htmlContent = '

' + escaped + '

';\n this._conversationPartialMessage.isPartial = false;\n this._conversationPartialMessage = null;\n } else {\n this.addMessage({\n role: 'user',\n content: text\n });\n }\n this.scrollToBottom();\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantToken\", (sessionId, messageId, token, responseId, appearance) => {\n if (!this._conversationAssistantMessage) {\n this.stopAudio();\n this.hideTypingIndicator();\n\n // Ensure no stale streaming indicators remain from prior messages.\n for (var j = 0; j < this.messages.length; j++) {\n if (this.messages[j].isStreaming) {\n this.messages[j].isStreaming = false;\n }\n }\n\n var msgIndex = this.messages.length;\n var newMessage = {\n id: messageId,\n role: \"assistant\",\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n appearance: this.normalizeAssistantAppearance(appearance),\n };\n this.messages.push(newMessage);\n this._conversationAssistantMessage = { index: msgIndex, content: '' };\n }\n\n this._conversationAssistantMessage.content += token;\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n if (!msg.appearance) {\n msg.appearance = this.normalizeAssistantAppearance(appearance);\n }\n msg.content = this._conversationAssistantMessage.content;\n msg.htmlContent = parseMarkdownContent(msg.content, msg);\n this.$nextTick(() => {\n renderChartsInMessage(msg);\n this.scrollToBottom();\n });\n }\n });\n\n this.connection.on(\"ReceiveConversationAssistantComplete\", (sessionId, messageId) => {\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n });\n\n this.connection.on(\"ReceiveAudioChunk\", (sessionId, base64Audio, contentType) => {\n if (base64Audio) {\n const binaryString = atob(base64Audio);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n this.audioChunks.push(bytes);\n }\n });\n\n this.connection.on(\"ReceiveAudioComplete\", (sessionId) => {\n this.playCollectedAudio();\n });\n\n this.connection.on(\"ReceiveNotification\", (notification) => {\n this.receiveNotification(notification);\n });\n\n this.connection.on(\"UpdateNotification\", (notification) => {\n this.updateNotification(notification);\n });\n\n this.connection.on(\"RemoveNotification\", (notificationType) => {\n this.removeNotification(notificationType);\n });\n\n this.connection.onreconnecting(() => {\n console.warn(\"SignalR: reconnecting...\");\n });\n\n this.connection.onreconnected(() => {\n console.info(\"SignalR: reconnected.\");\n\n if (this.isSessionStarted) {\n this.reloadCurrentSession();\n } else if (config.autoCreateSession) {\n this.startNewSession();\n }\n });\n\n this.connection.onclose((error) => {\n if (this.isNavigatingAway) {\n return;\n }\n\n if (error) {\n console.warn(\"SignalR connection closed with error:\", error.message || error);\n }\n });\n\n try {\n await this.connection.start();\n } catch (err) {\n console.error(\"SignalR Connection Error: \", err);\n }\n },\n addMessageInternal(message) {\n if (message.role === 'assistant') {\n message.appearance = this.normalizeAssistantAppearance(message.appearance);\n }\n\n if (message.content && !message.htmlContent) {\n message.htmlContent = parseMarkdownContent(message.content, message);\n }\n this.fireEvent(new CustomEvent(\"addingOpenAIPromotMessage\", { detail: { message: message } }));\n this.messages.push(message);\n\n this.$nextTick(() => {\n this.fireEvent(new CustomEvent(\"addedOpenAIPromotMessage\", { detail: { message: message } }));\n });\n },\n addMessage(message) {\n\n // Ensure userRating is always defined for Vue reactivity.\n if (message.userRating === undefined) {\n message.userRating = null;\n }\n\n if (message.content) {\n let processedContent = message.content.trim();\n message.references = normalizeReferences(message.references);\n\n if (message.references && typeof message.references === \"object\" && Object.keys(message.references).length) {\n\n // Only include references that were actually cited in the response.\n const citedRefs = Object.entries(message.references).filter(([key]) => processedContent.includes(key));\n\n if (citedRefs.length) {\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders.\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processedContent = processedContent.replaceAll(key, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processedContent = processedContent.replaceAll(value._placeholder, `${value._displayIndex}`);\n }\n\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n processedContent = processedContent.replaceAll('
', ',');\n\n processedContent += '

';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processedContent += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})
`\n : `**${value._displayIndex}**. ${label}
`;\n }\n }\n }\n\n message.content = processedContent;\n message.htmlContent = parseMarkdownContent(processedContent, message);\n }\n\n this.addMessageInternal(message);\n this.hidePlaceholder();\n\n this.$nextTick(() => {\n // Render any pending charts once the DOM is updated\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n addMessages(messages) {\n\n for (let i = 0; i < messages.length; i++) {\n this.addMessageInternal(messages[i]);\n }\n\n this.hidePlaceholder();\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n hidePlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.add('d-none');\n }\n this.isPlaceholderVisible = false;\n },\n showPlaceholder() {\n if (this.placeholder) {\n this.placeholder.classList.remove('d-none');\n }\n this.isPlaceholderVisible = true;\n },\n isOrchestratorAvailable() {\n return config.isOrchestratorAvailable !== false;\n },\n applyOrchestratorAvailability() {\n if (this.isOrchestratorAvailable()) {\n return true;\n }\n\n const unavailableMessage = config.orchestratorUnavailableMessage || \"This orchestrator is not currently available.\";\n\n if (this.inputElement) {\n this.inputElement.disabled = true;\n this.inputElement.value = '';\n this.inputElement.placeholder = unavailableMessage;\n }\n\n if (this.buttonElement) {\n this.buttonElement.disabled = true;\n }\n\n if (this.micButtonElement) {\n this.micButtonElement.disabled = true;\n this.micButtonElement.style.display = 'none';\n }\n\n if (this.conversationButtonElement) {\n this.conversationButtonElement.disabled = true;\n this.conversationButtonElement.style.display = 'none';\n }\n\n return false;\n },\n fireEvent(event) {\n document.dispatchEvent(event);\n },\n isIndicator(message) {\n return message.role === 'indicator';\n },\n sendMessage() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n let trimmedPrompt = this.prompt.trim();\n\n if (!trimmedPrompt) {\n return;\n }\n\n // Stop any active recording before sending.\n if (this.isRecording) {\n this.stopRecording();\n }\n\n // Prevent stale ReceiveTranscript events from repopulating the prompt.\n this._audioInputSent = true;\n\n // In single-response mode, clear all previous messages.\n if (this.singleResponseMode) {\n this.messages.splice(0, this.messages.length);\n }\n\n this.addMessage({\n role: 'user',\n content: trimmedPrompt\n });\n\n this.streamMessage(this.getProfileId(), trimmedPrompt, null);\n this.inputElement.value = '';\n this.prompt = '';\n },\n startRecording() {\n if (this.isRecording || !this.connection) {\n return;\n }\n\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this.preRecordingPrompt = this.prompt;\n this._audioInputSent = false;\n\n var subject = new signalR.Subject();\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var pendingChunk = Promise.resolve();\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n subject.next(base64);\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => subject.complete());\n });\n\n var language = navigator.language || document.documentElement.lang || 'en-US';\n this.connection.send(\"SendAudioStream\", profileId, sessionId, subject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n this.updateMicButton();\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n });\n },\n stopRecording() {\n if (!this.isRecording || !this.mediaRecorder) {\n return;\n }\n\n this.mediaRecorder.stop();\n this.isRecording = false;\n this.updateMicButton();\n },\n toggleRecording() {\n if (this.isRecording) {\n this.stopRecording();\n } else {\n this.startRecording();\n }\n },\n updateMicButton() {\n if (!this.micButton) {\n return;\n }\n\n if (this.isRecording) {\n this.micButton.classList.add('stt-recording');\n this.micButton.innerHTML = '';\n } else {\n this.micButton.classList.remove('stt-recording');\n this.micButton.innerHTML = '';\n }\n },\n streamMessage(profileId, trimmedPrompt, sessionProfileId) {\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n\n this.streamingStarted();\n this.showTypingIndicator();\n this.autoScroll = true;\n\n var content = '';\n var references = {};\n var lastResponseId = null;\n\n // Get the index after showing typing indicator.\n var messageIndex = this.messages.length;\n var currentSessionId = this.getSessionId();\n\n this.stream = this.connection.stream(\"SendMessage\", profileId, trimmedPrompt, currentSessionId, sessionProfileId)\n .subscribe({\n next: (chunk) => {\n let message = this.messages[messageIndex];\n\n if (!message) {\n\n if (chunk.sessionId && !currentSessionId) {\n this.initializeSession(chunk.sessionId);\n }\n\n this.hideTypingIndicator();\n // Re-assign the index after hiding the typing indicator.\n messageIndex = this.messages.length;\n let newMessage = {\n id: chunk.messageId,\n role: \"assistant\",\n title: chunk.title,\n content: \"\",\n htmlContent: \"\",\n isStreaming: true,\n userRating: null,\n };\n\n this.messages.push(newMessage);\n\n message = newMessage;\n }\n\n if (chunk.title && (!message.title || message.title !== chunk.title)) {\n message.title = chunk.title;\n }\n\n if (chunk.references && typeof chunk.references === \"object\" && Object.keys(chunk.references).length) {\n\n for (const [key, value] of Object.entries(chunk.references)) {\n references[key] = normalizeReference(value) ?? {};\n }\n }\n\n if (chunk.content) {\n\n // When the responseId changes (e.g., after an internal tool call),\n // insert a line break to visually separate response segments.\n if (chunk.responseId && lastResponseId && chunk.responseId !== lastResponseId) {\n content += '\\n\\n';\n }\n\n if (chunk.responseId) {\n lastResponseId = chunk.responseId;\n }\n\n let processedContent = chunk.content;\n\n for (const [key, value] of Object.entries(references)) {\n processedContent = processedContent.replaceAll(key, `${value.index}`);\n }\n\n // Append processed content to the message.\n // if we have multiple references, add a comma to ensure we don't concatenate numbers.\n content += processedContent.replaceAll('
', ',');\n }\n\n // Update the existing message\n message.content = content;\n\n message.htmlContent = parseMarkdownContent(content, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n },\n complete: () => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n if (!msg || !msg.content) {\n // No content received at all.\n this.hideTypingIndicator();\n }\n\n // Trigger text-to-speech only in conversation mode.\n if (this.isConversationMode && this.textToSpeechEnabled && msg && msg.content) {\n this.synthesizeSpeech(msg.content);\n }\n\n this.stream?.dispose();\n this.stream = null;\n },\n error: (err) => {\n this.processReferences(references, messageIndex);\n this.streamingFinished();\n\n let msg = this.messages[messageIndex];\n if (msg) {\n msg.isStreaming = false;\n }\n\n this.hideTypingIndicator();\n\n if (!this.isNavigatingAway) {\n this.addMessage(this.getServiceDownMessage());\n }\n\n this.stream?.dispose();\n this.stream = null;\n\n console.error(\"Stream error:\", err);\n }\n });\n },\n getServiceDownMessage() {\n let newMessage = {\n role: \"assistant\",\n content: \"Our service is currently unavailable. Please try again later. We apologize for the inconvenience.\",\n htmlContent: \"\",\n };\n\n return newMessage;\n },\n processReferences(references, messageIndex) {\n references = normalizeReferences(references);\n\n if (Object.keys(references).length) {\n\n let message = this.messages[messageIndex];\n const content = message.content || '';\n\n // Only include references that were actually cited in the response.\n // Check both raw [doc:N] markers and already-rendered tags from streaming.\n const citedRefs = Object.entries(references).filter(([key, value]) =>\n content.includes(key) || content.includes(`${value.index}`)\n );\n\n if (!citedRefs.length) {\n return;\n }\n\n // Sort by original index so display indices follow a natural order.\n citedRefs.sort(([, a], [, b]) => a.index - b.index);\n\n // Phase 1: Replace all markers with unique placeholders to avoid collisions during remapping.\n let processed = content.trim();\n let displayIndex = 1;\n for (const [key, value] of citedRefs) {\n const placeholder = `__CITE_${value.index}__`;\n processed = processed.replaceAll(key, placeholder);\n processed = processed.replaceAll(`${value.index}`, placeholder);\n value._displayIndex = displayIndex++;\n value._placeholder = placeholder;\n }\n\n // Phase 2: Replace placeholders with sequential display indices.\n for (const [, value] of citedRefs) {\n processed = processed.replaceAll(value._placeholder, `${value._displayIndex}`);\n }\n\n processed = processed.replaceAll('', ',');\n\n processed += '

';\n\n for (const [key, value] of citedRefs) {\n const label = value.text || key;\n processed += value.link\n ? `**${value._displayIndex}**. [${label}](${value.link})
`\n : `**${value._displayIndex}**. ${label}
`;\n }\n\n message.content = processed;\n message.htmlContent = parseMarkdownContent(processed, message);\n\n this.messages[messageIndex] = message;\n\n this.$nextTick(() => {\n renderChartsInMessage(message);\n this.scrollToBottom();\n });\n }\n },\n streamingStarted() {\n var stopIcon = this.buttonElement.getAttribute('data-stop-icon');\n\n if (stopIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(stopIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.setAttribute('disabled', 'disabled');\n }\n },\n streamingFinished() {\n var startIcon = this.buttonElement.getAttribute('data-start-icon');\n\n if (startIcon) {\n this.buttonElement.replaceChildren(DOMPurify.sanitize(startIcon, { RETURN_DOM_FRAGMENT: true }));\n }\n\n if (this.inputElement) {\n this.inputElement.removeAttribute('disabled');\n this.inputElement.focus();\n }\n\n // Directly manipulate the DOM to stop all streaming animations.\n if (this.chatContainer) {\n var icons = this.chatContainer.querySelectorAll('.ai-streaming-icon');\n for (var i = 0; i < icons.length; i++) {\n icons[i].classList.remove('ai-streaming-icon');\n icons[i].classList.add('ai-bot-icon');\n }\n }\n\n // Also update Vue data for consistency.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n },\n handleExternalTtsStop(e) {\n if (e?.detail?.sourceId === this.ttsInstanceId) {\n return;\n }\n\n this.stopAudio(false);\n },\n synthesizeSpeech(text, cacheIndex) {\n if (!this.textToSpeechEnabled || !text || !this.connection) {\n return;\n }\n\n this.audioChunks = [];\n this.isPlayingAudio = true;\n this._ttsCacheIndex = cacheIndex !== undefined ? cacheIndex : -1;\n\n this.connection.invoke(\"SynthesizeSpeech\", this.getProfileId(), this.getSessionId(), text, this.ttsVoiceName)\n .catch(err => {\n console.error(\"TTS synthesis error:\", err);\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this._ttsCacheIndex = -1;\n });\n },\n toggleMessageTts(message, index) {\n if (this.ttsPlayingMessageIndex === index) {\n this.stopAudio();\n return;\n }\n\n this.stopAudio(false);\n window.dispatchEvent(new CustomEvent('crestapps-ai-chat-stop-tts', {\n detail: { sourceId: this.ttsInstanceId }\n }));\n this.ttsPlayingMessageIndex = index;\n\n if (this.ttsAudioCache[index]) {\n this.playAudioBlob(this.ttsAudioCache[index]);\n return;\n }\n\n this.synthesizeSpeech(message.content, index);\n },\n playCollectedAudio() {\n if (this.audioChunks.length === 0) {\n if (!this.currentAudioElement && this.audioPlayQueue.length === 0) {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n }\n return;\n }\n\n const totalLength = this.audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const combined = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of this.audioChunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n this.audioChunks = [];\n\n const blob = new Blob([combined], { type: 'audio/mp3' });\n\n if (this._ttsCacheIndex >= 0) {\n this.ttsAudioCache[this._ttsCacheIndex] = blob;\n this._ttsCacheIndex = -1;\n }\n\n // If audio is already playing, queue this blob for sequential playback.\n if (this.currentAudioElement) {\n this.audioPlayQueue.push(blob);\n return;\n }\n\n this.playAudioBlob(blob);\n },\n playAudioBlob(blob) {\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n\n this.currentAudioUrl = url;\n this.currentAudioElement = audio;\n this.isPlayingAudio = true;\n\n audio.addEventListener('ended', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.addEventListener('error', () => {\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.playNextInQueue();\n });\n\n audio.play().catch(err => {\n console.error(\"Audio playback error:\", err);\n this.currentAudioElement = null;\n this.currentAudioUrl = null;\n URL.revokeObjectURL(url);\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n });\n },\n playNextInQueue() {\n if (this.audioPlayQueue.length > 0) {\n var nextBlob = this.audioPlayQueue.shift();\n this.playAudioBlob(nextBlob);\n } else {\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n this.conversationModeOnAudioEnded();\n }\n },\n stopAudio() {\n if (this.currentAudioElement) {\n this.currentAudioElement.pause();\n this.currentAudioElement.currentTime = 0;\n this.currentAudioElement = null;\n }\n if (this.currentAudioUrl) {\n URL.revokeObjectURL(this.currentAudioUrl);\n this.currentAudioUrl = null;\n }\n this.audioChunks = [];\n this.audioPlayQueue = [];\n this.isPlayingAudio = false;\n this.ttsPlayingMessageIndex = -1;\n },\n toggleConversationMode() {\n if (this.isConversationMode) {\n this.stopConversationMode();\n } else {\n this.startConversationMode();\n }\n },\n startConversationMode() {\n if (!this.conversationModeEnabled || this.isConversationMode || !this.connection) {\n return;\n }\n\n this.isConversationMode = true;\n this.updateConversationButton();\n this._conversationPartialTranscript = '';\n this._conversationAssistantMessage = null;\n this._conversationPartialMessage = null;\n\n // Remove any previous conversation ended notification.\n this.removeNotification('conversation-ended');\n navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } })\n .then(stream => {\n var mimeType = MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')\n ? 'audio/ogg;codecs=opus'\n : MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\n ? 'audio/webm;codecs=opus'\n : 'audio/webm';\n\n this.mediaRecorder = new MediaRecorder(stream, {\n mimeType: mimeType,\n audioBitsPerSecond: 128000,\n });\n\n this._conversationSubject = new signalR.Subject();\n this._conversationStream = stream;\n\n // Create an AnalyserNode for volume-based interrupt detection.\n // During TTS playback, detect when the user speaks above\n // the threshold to stop TTS (interrupt). Audio chunks are\n // always forwarded — browser echo cancellation handles\n // speaker echo so the STT stream has no gaps.\n var AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n this._conversationAudioCtx = new AudioCtx();\n this._conversationAnalyser = this._conversationAudioCtx.createAnalyser();\n this._conversationAnalyser.fftSize = 256;\n var micSource = this._conversationAudioCtx.createMediaStreamSource(stream);\n micSource.connect(this._conversationAnalyser);\n }\n\n var pendingChunk = Promise.resolve();\n var analyser = this._conversationAnalyser;\n var interruptVolumeThreshold = 30;\n\n this.mediaRecorder.addEventListener('dataavailable', (e) => {\n if (e.data && e.data.size > 0) {\n // During TTS playback, check mic volume to detect\n // user interruption (speaking above threshold).\n if (this.isPlayingAudio && analyser) {\n var freqData = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(freqData);\n var sum = 0;\n for (var k = 0; k < freqData.length; k++) { sum += freqData[k]; }\n var avg = sum / freqData.length;\n\n if (avg >= interruptVolumeThreshold) {\n // User is speaking — interrupt TTS playback.\n this.stopAudio();\n }\n }\n\n // Always send audio to STT — browser echo cancellation\n // handles speaker echo; continuous audio avoids gaps\n // that increase recognition latency.\n pendingChunk = pendingChunk.then(async () => {\n var data = await e.data.arrayBuffer();\n var uint8Array = new Uint8Array(data);\n var binaryString = uint8Array.reduce(function (str, byte) { return str + String.fromCharCode(byte); }, '');\n var base64 = btoa(binaryString);\n try {\n this._conversationSubject.next(base64);\n } catch (err) {\n // Subject may have been completed already.\n }\n });\n }\n });\n\n this.mediaRecorder.addEventListener('stop', () => {\n stream.getTracks().forEach(track => track.stop());\n pendingChunk.then(() => {\n try {\n this._conversationSubject.complete();\n } catch (err) {\n // Already completed.\n }\n });\n });\n\n var profileId = this.getProfileId();\n var sessionId = this.getSessionId() || '';\n var language = navigator.language || document.documentElement.lang || 'en-US';\n\n this.connection.send(\"StartConversation\", profileId, sessionId, this._conversationSubject, mimeType, language);\n this.mediaRecorder.start(250);\n this.isRecording = true;\n })\n .catch(err => {\n console.error('Microphone access denied:', err);\n this.isConversationMode = false;\n this.updateConversationButton();\n });\n },\n stopConversationMode() {\n if (!this.isConversationMode) {\n return;\n }\n\n this.isConversationMode = false;\n this.updateConversationButton();\n\n // Signal the server to cancel all in-progress STT/TTS streams immediately.\n if (this.connection) {\n this.connection.invoke(\"StopConversation\").catch(function () { });\n }\n\n if (this.isRecording && this.mediaRecorder) {\n this.mediaRecorder.stop();\n this.isRecording = false;\n }\n\n this.stopAudio();\n this._conversationPartialTranscript = '';\n this._conversationPartialMessage = null;\n\n // Clean up the AudioContext used for volume monitoring.\n if (this._conversationAudioCtx) {\n this._conversationAudioCtx.close().catch(function () { });\n this._conversationAudioCtx = null;\n this._conversationAnalyser = null;\n }\n\n // Mark any in-flight assistant message as done to stop the spinner.\n if (this._conversationAssistantMessage) {\n var msg = this.messages[this._conversationAssistantMessage.index];\n if (msg) {\n msg.isStreaming = false;\n }\n this._conversationAssistantMessage = null;\n }\n\n // Safety net: clear all lingering streaming indicators.\n for (var i = 0; i < this.messages.length; i++) {\n if (this.messages[i].isStreaming) {\n this.messages[i].isStreaming = false;\n }\n }\n\n // Show a \"conversation ended\" notification system message.\n this.receiveNotification({\n type: 'conversation-ended',\n content: 'Conversation ended.',\n icon: 'fa-solid fa-circle-check',\n dismissible: true,\n autoDismissMs: 5000\n });\n },\n updateConversationButton() {\n if (!this.conversationButton) {\n return;\n }\n\n if (this.isConversationMode) {\n this.conversationButton.classList.add('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-dark', 'btn-outline-secondary');\n this.conversationButton.title = this.conversationButton.getAttribute('data-end-title') || 'End Conversation';\n var endHtml = this.conversationButton.getAttribute('data-end-html');\n if (endHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(endHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n } else {\n this.conversationButton.classList.remove('active', 'btn-primary');\n this.conversationButton.classList.remove('btn-dark', 'btn-outline-secondary');\n this.conversationButton.classList.add('btn-outline-dark');\n this.conversationButton.blur();\n this.conversationButton.title = this.conversationButton.getAttribute('data-start-title') || 'Start Conversation';\n var startHtml = this.conversationButton.getAttribute('data-start-html');\n if (startHtml) {\n this.conversationButton.replaceChildren(DOMPurify.sanitize(startHtml, { RETURN_DOM_FRAGMENT: true }));\n }\n }\n },\n conversationModeSendPrompt() {\n // Legacy: only used by AudioInput mode's ReceiveTranscript.\n },\n conversationModeOnAudioEnded() {\n // Legacy: in conversation mode, audio playback continuation\n // is handled by the persistent stream. This method is only\n // called from playCollectedAudio for non-conversation TTS.\n },\n generatePrompt(element) {\n if (!element) {\n console.error('The element paramter is required.');\n\n return;\n }\n\n let templateProfileId = element.getAttribute('data-profile-id');\n let sessionId = this.getSessionId();\n let sessionProfileId = this.getProfileId();\n\n if (!templateProfileId || !sessionId) {\n\n console.error('The given element is missing data-profile-id or the session has not yet started.');\n return;\n }\n\n // streamMessage() already shows the typing indicator.\n this.streamMessage(templateProfileId, null, sessionProfileId);\n },\n createSessionUrl(baseUrl, param, value) {\n\n const fullUrl = baseUrl.toLowerCase().startsWith('http') ? baseUrl : window.location.origin + baseUrl;\n const url = new URL(fullUrl);\n\n url.searchParams.set(param, value);\n\n return url.toString();\n },\n showTypingIndicator() {\n this.addMessage({\n role: 'indicator',\n htmlContent: config.indicatorTemplate\n });\n },\n hideTypingIndicator() {\n const originalLength = this.messages.length;\n this.messages = this.messages.filter(msg => msg.role !== 'indicator');\n const removedCount = originalLength - this.messages.length;\n return removedCount;\n },\n receiveNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n } else {\n this.notifications.push(notification);\n }\n this.scheduleNotificationDismiss(notification);\n this.$nextTick(() => {\n this.scrollToBottom();\n });\n },\n updateNotification(notification) {\n if (!notification || !notification.type) {\n return;\n }\n this.clearNotificationDismiss(notification.type);\n var existingIndex = this.notifications.findIndex(n => n.type === notification.type);\n if (existingIndex >= 0) {\n this.notifications.splice(existingIndex, 1, notification);\n this.scheduleNotificationDismiss(notification);\n }\n },\n scheduleNotificationDismiss(notification) {\n if (!notification || !notification.type || !notification.autoDismissMs || notification.autoDismissMs <= 0) {\n return;\n }\n this.notificationDismissTimers[notification.type] = setTimeout(() => {\n this.removeNotification(notification.type);\n }, notification.autoDismissMs);\n },\n clearNotificationDismiss(notificationType) {\n var timerId = this.notificationDismissTimers[notificationType];\n if (!timerId) {\n return;\n }\n clearTimeout(timerId);\n delete this.notificationDismissTimers[notificationType];\n },\n removeNotification(notificationType) {\n this.clearNotificationDismiss(notificationType);\n this.notifications = this.notifications.filter(n => n.type !== notificationType);\n },\n dismissNotification(notificationType) {\n this.removeNotification(notificationType);\n },\n handleNotificationAction(notificationType, actionName) {\n if (!this.connection) {\n return;\n }\n var sessionId = this.getSessionId();\n this.connection.invoke(\"HandleNotificationAction\", sessionId, notificationType, actionName).catch(function (err) {\n console.error(\"Error handling notification action:\", err);\n });\n },\n scrollToBottom() {\n if (!this.autoScroll) {\n return;\n }\n setTimeout(() => {\n this.chatContainer.scrollTop = this.chatContainer.scrollHeight - this.chatContainer.clientHeight;\n }, 50);\n },\n handleUserInput(event) {\n this.prompt = event.target.value;\n },\n getProfileId() {\n return this.inputElement.getAttribute('data-profile-id');\n },\n setSessionId(sessionId) {\n this.inputElement.setAttribute('data-session-id', sessionId || '');\n },\n resetSession() {\n this.stopRecording();\n this.setSessionId('');\n this.isSessionStarted = false;\n this.sessionRating = null;\n if (this.widgetIsInitialized) {\n localStorage.removeItem(this.chatWidgetStateSession);\n }\n this.messages = [];\n this.documents = [];\n if (!config.autoCreateSession) {\n this.showPlaceholder();\n }\n\n if (config.autoCreateSession) {\n this.startNewSession();\n }\n },\n startNewSession() {\n if (!this.applyOrchestratorAvailability()) {\n return;\n }\n\n const profileId = this.getProfileId();\n if (!profileId || !this.connection) {\n return;\n }\n\n this.connection.invoke(\"StartSession\", profileId, null).catch(err => console.error(err));\n },\n initializeApp() {\n this.inputElement = document.querySelector(config.inputElementSelector);\n this.buttonElement = document.querySelector(config.sendButtonElementSelector);\n this.chatContainer = document.querySelector(config.chatContainerElementSelector);\n this.placeholder = document.querySelector(config.placeholderElementSelector);\n this.applyOrchestratorAvailability();\n\n const sessionId = this.getSessionId();\n if (!hasWidgetConfig && sessionId) {\n this.loadSession(sessionId);\n } else if (this.isOrchestratorAvailable() && config.autoCreateSession && !hasWidgetConfig && !sessionId) {\n this.startNewSession();\n }\n\n // Initialize document bar if enabled.\n if (config.sessionDocumentsEnabled && config.documentBarSelector) {\n this.documentBar = document.querySelector(config.documentBarSelector);\n if (this.documentBar) {\n this.renderDocumentBar();\n\n // Create hidden file input for document uploads.\n var fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.id = 'ai-chat-doc-input';\n fileInput.className = 'd-none';\n fileInput.multiple = true;\n if (config.allowedExtensions) {\n fileInput.accept = config.allowedExtensions;\n }\n fileInput.addEventListener('change', (e) => this.handleFileInputChange(e));\n this.documentBar.parentElement.appendChild(fileInput);\n\n // Set up drag-and-drop on the input area.\n var inputArea = this.inputElement ? this.inputElement.closest('.ai-admin-widget-input, .text-bg-light') : null;\n if (inputArea) {\n inputArea.addEventListener('dragover', (e) => this.handleDragOver(e));\n inputArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));\n inputArea.addEventListener('drop', (e) => this.handleDrop(e));\n }\n }\n }\n\n // Pause auto-scroll when the user manually scrolls up during streaming.\n this.chatContainer.addEventListener('scroll', () => {\n if (!this.stream) {\n return;\n }\n const threshold = 30;\n const atBottom = this.chatContainer.scrollHeight - this.chatContainer.clientHeight - this.chatContainer.scrollTop <= threshold;\n this.autoScroll = atBottom;\n });\n\n this.inputElement.addEventListener('keydown', event => {\n\n if (this.stream != null) {\n return;\n }\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n this.buttonElement.click();\n }\n });\n\n this.inputElement.addEventListener('input', (e) => {\n this.handleUserInput(e);\n\n if (e.target.value.trim()) {\n this.buttonElement.removeAttribute('disabled');\n } else {\n this.buttonElement.setAttribute('disabled', true);\n }\n });\n\n this.buttonElement.addEventListener('click', () => {\n\n if (this.stream != null) {\n this.stream.dispose();\n this.stream = null;\n\n this.streamingFinished();\n this.hideTypingIndicator();\n\n // Clean up: remove empty assistant message or stop streaming animation.\n if (this.messages.length > 0) {\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg.role === 'assistant' && !lastMsg.content) {\n this.messages.pop();\n } else if (lastMsg.isStreaming) {\n lastMsg.isStreaming = false;\n }\n }\n\n return;\n }\n\n this.sendMessage();\n });\n\n const promptGenerators = document.getElementsByClassName('profile-generated-prompt');\n\n for (var i = 0; i < promptGenerators.length; i++) {\n promptGenerators[i].addEventListener('click', (e) => {\n e.preventDefault();\n this.generatePrompt(e.target);\n });\n }\n\n const chatSessions = document.getElementsByClassName('chat-session-history-item');\n\n for (var i = 0; i < chatSessions.length; i++) {\n chatSessions[i].addEventListener('click', (e) => {\n e.preventDefault();\n\n var sessionId = e.target.getAttribute('data-session-id');\n\n if (!sessionId) {\n console.error('an element with the class chat-session-history-item with no data-session-id set.');\n\n return;\n }\n\n this.loadSession(sessionId);\n this.showChatScreen();\n });\n }\n\n for (let i = 0; i < config.messages.length; i++) {\n this.addMessage(config.messages[i]);\n }\n\n // Update feedback icons in the DOM after initial messages have rendered.\n this.$nextTick(() => {\n this.refreshAllFeedbackIcons();\n });\n\n // Delegate click for code block copy buttons.\n if (this.chatContainer) {\n this.chatContainer.addEventListener('click', (e) => {\n var btn = e.target.closest('.ai-code-copy-btn');\n if (!btn) {\n return;\n }\n\n var block = btn.closest('.ai-code-block') || btn.closest('pre');\n if (!block) {\n return;\n }\n\n var codeEl = block.querySelector('code');\n if (codeEl) {\n navigator.clipboard.writeText(codeEl.textContent);\n var copiedText = config.codeCopiedText || 'Copied!';\n btn.innerHTML = ' ' + copiedText;\n setTimeout(() => {\n btn.innerHTML = '';\n }, 2000);\n }\n });\n }\n\n // Initialize speech-to-text microphone button.\n if (this.speechToTextEnabled && config.micButtonElementSelector) {\n this.micButton = document.querySelector(config.micButtonElementSelector);\n if (this.micButton) {\n this.micButton.style.display = '';\n this.micButton.addEventListener('click', () => {\n this.toggleRecording();\n });\n }\n }\n\n // Initialize conversation mode button.\n if (this.conversationModeEnabled && config.conversationButtonElementSelector) {\n this.conversationButton = document.querySelector(config.conversationButtonElementSelector);\n if (this.conversationButton) {\n this.conversationButton.addEventListener('click', () => {\n this.toggleConversationMode();\n });\n }\n }\n },\n loadSession(sessionId) {\n this.connection.invoke(\"LoadSession\", sessionId).catch(err => console.error(err));\n },\n reloadCurrentSession() {\n\n var sessionId = this.getSessionId();\n if (sessionId) {\n this.loadSession(sessionId);\n }\n },\n initializeSession(sessionId, force) {\n if (this.isSessionStarted && !force) {\n return\n }\n this.fireEvent(new CustomEvent(\"initializingSessionOpenAIChat\", { detail: { sessionId: sessionId } }))\n this.setSessionId(sessionId);\n this.isSessionStarted = true;\n\n if (this.widgetIsInitialized) {\n localStorage.setItem(this.chatWidgetStateSession, sessionId);\n }\n },\n initializeWidget() {\n\n if (!config.widget.chatWidgetContainer) {\n console.error('The widget chatWidgetContainer is required.');\n return;\n }\n\n if (!config.widget.chatWidgetStateName) {\n console.error('The widget chatWidgetStateName is required.');\n return;\n }\n\n const chatWidgetContainer = document.querySelector(config.widget.chatWidgetContainer);\n\n if (!chatWidgetContainer) {\n return;\n }\n\n if (config.widget.chatHistorySection) {\n this.chatHistorySection = document.querySelector(config.widget.chatHistorySection);\n }\n\n this.chatWidgetStateName = config.widget.chatWidgetStateName;\n this.chatWidgetStateSession = config.widget.chatWidgetStateName + 'Session';\n this.chatWidgetLayoutKey = config.widget.chatWidgetStateName + 'Layout';\n this.widgetContainerElement = chatWidgetContainer;\n this.widgetToggleButtonElement = config.widget.toggleButtonSelector\n ? document.querySelector(config.widget.toggleButtonSelector)\n : null;\n this.widgetResetSizeButtonElement = config.widget.resetSizeButtonSelector\n ? document.querySelector(config.widget.resetSizeButtonSelector)\n : null;\n this.widgetDefaultWidth = parsePixelValue(config.widget.defaultWidth) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).width) ||\n 380;\n this.widgetDefaultHeight = parsePixelValue(config.widget.defaultHeight) ||\n parsePixelValue(window.getComputedStyle(chatWidgetContainer).height) ||\n 520;\n this.widgetIsInitialized = true;\n\n if (config.widget.enableResizing) {\n chatWidgetContainer.classList.add('ai-chat-widget-resizable');\n chatWidgetContainer.style.minWidth = (parsePixelValue(config.widget.minWidth) || 320) + 'px';\n chatWidgetContainer.style.minHeight = (parsePixelValue(config.widget.minHeight) || 420) + 'px';\n\n if (typeof ResizeObserver !== 'undefined') {\n this.widgetResizeObserver = new ResizeObserver(() => {\n this.persistWidgetPanelSize();\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n });\n\n this.widgetResizeObserver.observe(chatWidgetContainer);\n }\n }\n\n var dragHandleSelector = config.widget.dragHandleSelector || '.ai-chat-widget-header';\n var dragHandle = chatWidgetContainer.querySelector(dragHandleSelector);\n\n if (config.widget.enableDragging && dragHandle) {\n dragHandle.classList.add('ai-chat-widget-drag-handle');\n chatWidgetContainer.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(chatWidgetContainer, dragHandle, 'panel', false);\n }\n\n if (config.widget.enableDragging && this.widgetToggleButtonElement) {\n this.widgetToggleButtonElement.classList.add('ai-chat-widget-draggable');\n this.attachDraggableWidgetElement(this.widgetToggleButtonElement, this.widgetToggleButtonElement, 'toggle', true);\n }\n\n if (this.widgetResetSizeButtonElement) {\n this.widgetResetSizeButtonElement.addEventListener('click', (event) => {\n event.preventDefault();\n this.resetWidgetSize();\n });\n }\n\n this.restoreWidgetLayout();\n\n if (!this.widgetViewportResizeHandler) {\n this.widgetViewportResizeHandler = () => {\n this.constrainWidgetElementsToViewport();\n this.updateWidgetResetSizeButtonVisibility();\n };\n\n window.addEventListener('resize', this.widgetViewportResizeHandler);\n }\n\n // Auto-load the last session so the user always sees previous chat history.\n this.reloadCurrentSession();\n\n if (config.autoCreateSession && !this.getSessionId()) {\n this.startNewSession();\n }\n\n if (config.widget.showHistoryButton && this.chatHistorySection) {\n\n const showHistoryButton = document.querySelector(config.widget.showHistoryButton);\n\n if (showHistoryButton) {\n showHistoryButton.addEventListener('click', () => {\n this.chatHistorySection.classList.toggle('show');\n });\n }\n\n if (config.widget.closeHistoryButton) {\n var closeHistoryButton = document.querySelector(config.widget.closeHistoryButton);\n\n if (closeHistoryButton) {\n closeHistoryButton.addEventListener('click', () => {\n this.showChatScreen();\n });\n }\n }\n }\n\n if (config.widget.newChatButton) {\n const newChatButton = document.querySelector(config.widget.newChatButton);\n\n if (newChatButton) {\n newChatButton.addEventListener('click', () => {\n this.resetSession();\n this.showChatScreen();\n });\n }\n }\n },\n showChatScreen() {\n\n if (!this.chatHistorySection) {\n return;\n }\n\n this.chatHistorySection.classList.remove('show');\n },\n getSessionId() {\n let sessionId = this.inputElement.getAttribute('data-session-id');\n\n if (!sessionId && this.widgetIsInitialized) {\n sessionId = localStorage.getItem(this.chatWidgetStateSession);\n }\n\n return sessionId;\n },\n copyResponse(message) {\n navigator.clipboard.writeText(message);\n },\n updateFeedbackIcons(container, userRating) {\n if (!container) {\n return;\n }\n\n var upBtn = container.querySelector('.rate-up-btn');\n var downBtn = container.querySelector('.rate-down-btn');\n\n // Font Awesome SVG+JS replaces with , so we must replace\n // the entire button content and let Font Awesome re-process.\n if (upBtn) {\n var upClass = userRating === true ? 'fa-solid fa-thumbs-up' : 'fa-regular fa-thumbs-up';\n var upIcon = document.createElement('i');\n upIcon.className = upClass;\n upIcon.style.fontSize = '0.9rem';\n upBtn.textContent = '';\n upBtn.appendChild(upIcon);\n }\n\n if (downBtn) {\n var downClass = userRating === false ? 'fa-solid fa-thumbs-down' : 'fa-regular fa-thumbs-down';\n var downIcon = document.createElement('i');\n downIcon.className = downClass;\n downIcon.style.fontSize = '0.9rem';\n downBtn.textContent = '';\n downBtn.appendChild(downIcon);\n }\n\n // Trigger Font Awesome SVG+JS to convert the new elements.\n if (window.FontAwesome && FontAwesome.dom && FontAwesome.dom.i2svg) {\n FontAwesome.dom.i2svg({ node: container });\n }\n },\n refreshAllFeedbackIcons() {\n var containers = this.$el.querySelectorAll('.ai-chat-message-assistant-feedback');\n\n for (var i = 0; i < containers.length; i++) {\n var msgId = containers[i].getAttribute('data-message-id');\n var msg = this.messages.find(m => m.id === msgId);\n\n if (msg) {\n this.updateFeedbackIcons(containers[i], msg.userRating);\n }\n }\n },\n rateMessage(message, isPositive, event) {\n var sessionId = this.getSessionId();\n\n if (!sessionId || !message.id || !this.connection) {\n return;\n }\n\n // Toggle: clicking the same rating again clears it.\n var newRating = message.userRating === isPositive ? null : isPositive;\n message.userRating = newRating;\n\n // Find the feedback container by message ID for reliable DOM targeting.\n var feedbackContainer = this.$el.querySelector(\n '.ai-chat-message-assistant-feedback[data-message-id=\"' + message.id + '\"]'\n );\n\n this.updateFeedbackIcons(feedbackContainer, newRating);\n\n // Trigger spark animation after Font Awesome has re-processed icons.\n if (newRating !== null && feedbackContainer) {\n setTimeout(() => {\n var btnClass = isPositive ? '.rate-up-btn' : '.rate-down-btn';\n var btn = feedbackContainer.querySelector(btnClass);\n\n if (btn) {\n btn.classList.remove('spark-effect');\n void btn.offsetWidth;\n btn.classList.add('spark-effect');\n btn.addEventListener('animationend', function onEnd() {\n btn.removeEventListener('animationend', onEnd);\n btn.classList.remove('spark-effect');\n });\n }\n }, 50);\n }\n\n this.connection.invoke(\"RateMessage\", sessionId, message.id, isPositive).catch(function (err) {\n console.error('Failed to rate message:', err);\n });\n }\n },\n watch: {\n documents: {\n handler() { this.renderDocumentBar(); },\n deep: true\n },\n isUploading() { this.renderDocumentBar(); },\n isPlayingAudio() {\n // Reserved for future use — volume-based interrupt detection\n // no longer mutes tracks; browser echo cancellation handles echo.\n },\n isConversationMode(active) {\n // Hide/show mic button.\n if (this.micButton) {\n this.micButton.style.display = active ? 'none' : (this.speechToTextEnabled ? '' : 'none');\n }\n\n // Hide/show send button.\n if (this.buttonElement) {\n this.buttonElement.style.display = active ? 'none' : '';\n }\n\n // Disable/enable textarea.\n if (this.inputElement) {\n this.inputElement.disabled = active;\n if (active) {\n this.inputElement.placeholder = '';\n }\n }\n }\n },\n mounted() {\n (async () => {\n await this.startConnection();\n this.initializeApp();\n if (hasWidgetConfig) {\n this.initializeWidget();\n }\n })();\n\n window.addEventListener('beforeunload', this.handleBeforeUnload);\n window.addEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n },\n beforeUnmount() {\n window.removeEventListener('beforeunload', this.handleBeforeUnload);\n window.removeEventListener('crestapps-ai-chat-stop-tts', this.handleExternalTtsStop);\n\n this.stopAudio(false);\n\n if (this.stream) {\n this.stream.dispose();\n this.stream = null;\n }\n if (this.connection) {\n this.connection.stop();\n }\n },\n template: config.messageTemplate\n }).mount(config.appElementSelector);\n\n return app;\n };\n\n return {\n initialize: initialize\n };\n}();\n\n// Download chart as image via event delegation (DOMPurify strips inline onclick).\ndocument.addEventListener('click', function (e) {\n const btn = e.target.closest('.download-chart-btn');\n if (!btn) {\n return;\n }\n const chartId = btn.getAttribute('data-chart-id');\n const canvas = chartId ? document.getElementById(chartId) : null;\n if (!canvas) {\n console.error('Chart canvas not found:', chartId);\n return;\n }\n const link = document.createElement('a');\n link.download = 'chart-' + chartId + '.png';\n link.href = canvas.toDataURL('image/png');\n link.click();\n});\n\n// Intercept download clicks for data-URI images and convert to blob downloads.\ndocument.addEventListener('click', function (e) {\n const link = e.target.closest('.ai-download-image');\n if (!link) {\n return;\n }\n\n const container = link.closest('.generated-image-container');\n const img = container?.querySelector('img');\n if (!img) {\n return;\n }\n\n const src = img.src;\n if (!src || !src.startsWith('data:')) {\n return; // Normal URL – let the default behaviour handle it.\n }\n\n e.preventDefault();\n\n fetch(src)\n .then(function (res) { return res.blob(); })\n .then(function (blob) {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = link.getAttribute('download') || 'generated-image.png';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n setTimeout(function () { URL.revokeObjectURL(url); }, 100);\n })\n .catch(function (err) { console.error('Failed to download image:', err); });\n});\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css new file mode 100644 index 00000000..f1a74400 --- /dev/null +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css @@ -0,0 +1,362 @@ +.ai-chat-msg-role { + font-size: 1.25rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.03em; + margin-bottom: 0.35rem; +} + +.ai-chat-msg-role-user { + color: var(--bs-primary, #0d6efd); +} + +.ai-chat-msg-role-assistant { + color: var(--ai-chat-primary, #198754); +} + +.ai-chat-messages .ai-chat-message-item { + position: relative; + padding: 0.25rem 0; +} + +.ai-chat-messages .ai-chat-message-item + .ai-chat-message-item::before { + content: ''; + display: block; + width: 100%; + margin: 0.5rem auto 0.75rem; + border-top: 1px solid var(--bs-border-color, #dee2e6); +} + +.ai-chat-messages .ai-chat-message-item p:last-child { + margin-bottom: 0; +} + +.ai-chat-messages .ai-chat-message-body { + position: relative; + padding: 0; + overflow-wrap: break-word; + word-break: break-word; + min-width: 0; +} + +.ai-partial-transcript { + font-style: italic; + opacity: 0.7; +} + +.ai-chat-messages .message-buttons-container { + position: absolute; + right: 0.1rem; + bottom: 0; + display: inline-flex; + align-items: center; + gap: 0.35rem; + width: auto; + max-width: max-content; + opacity: 0; + pointer-events: none; + transition: opacity 0.15s ease-in-out; + background: rgba(255, 255, 255, 0.96); + padding: 0.2rem 0.35rem; + border-radius: 999px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); + margin-bottom: 1rem; + transform: translateY(50%); + z-index: 1; +} + +.ai-chat-messages .ai-chat-message-item:hover .message-buttons-container, +.ai-chat-messages .ai-chat-message-item:focus-within .message-buttons-container { + opacity: 1; + pointer-events: auto; +} + +.ai-chat-messages .message-buttons-container:has(.tts-playing) { + opacity: 1; + pointer-events: auto; +} + +.ai-chat-messages .message-buttons-container > .button-message-toolbox { + display: inline-flex; + align-items: center; + justify-content: center; + flex: 0 0 auto; + width: 1.75rem; + height: 1.75rem; + margin: 0 !important; + padding: 0 !important; + border-radius: 50%; + color: var(--bs-secondary-color, #6c757d) !important; + text-decoration: none; +} + +.ai-chat-messages .message-buttons-container .ai-chat-message-assistant-feedback { + display: inline-flex; + align-items: center; + gap: 0.35rem; +} + +.ai-chat-messages .message-buttons-container > .button-message-toolbox:hover, +.ai-chat-messages .message-buttons-container > .button-message-toolbox:focus { + color: var(--bs-body-color, #212529) !important; +} + +.ai-chat-messages .message-buttons-container .tts-playing { + color: var(--ai-chat-primary, #198754); +} + +@keyframes spark-burst { + 0% { + transform: scale(1); + opacity: 1; + } + 20% { + transform: scale(1.8); + opacity: 0.7; + } + 40% { + transform: scale(0.9); + opacity: 1; + } + 60% { + transform: scale(1.3); + } + 100% { + transform: scale(1); + } +} + +.spark-effect i, +.spark-effect svg { + display: inline-block; + animation: spark-burst 0.5s ease-out; +} + +.ai-chat-messages .ai-bot-icon { + color: currentColor; + display: inline-block; + animation: none; +} + +@keyframes ai-chat-streaming-effect { + 0% { opacity: 1; transform: rotate(0deg); } + 10% { opacity: 0.3; transform: rotate(0deg); } + 20% { opacity: 1; transform: rotate(0deg); } + 30% { opacity: 0.3; transform: rotate(0deg); } + 40% { opacity: 1; transform: rotate(0deg); } + 50% { opacity: 0.3; transform: rotate(0deg); } + 60% { opacity: 1; transform: rotate(0deg); } + 80% { opacity: 1; transform: rotate(360deg); } + 100% { opacity: 1; transform: rotate(360deg); } +} + +.ai-chat-messages .ai-streaming-icon { + color: currentColor; + display: inline-block; + animation: ai-chat-streaming-effect 4s ease-in-out infinite; +} + +.ai-chat-messages pre { + position: relative; + margin: 0; +} + +.ai-chat-messages .ai-code-block { + border: 1px solid var(--bs-border-color, #dee2e6); + border-radius: 0.5rem; + overflow: hidden; + margin: 0.75rem 0; + background: var(--bs-body-bg, #fff); +} + +.ai-chat-messages .ai-code-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.5rem 1rem; + font-size: 0.8rem; + min-height: 2rem; +} + +.ai-chat-messages .ai-code-lang { + font-weight: 600; + color: var(--bs-body-color, #212529); + text-transform: capitalize; +} + +.ai-chat-messages .ai-code-lang i { + color: var(--bs-secondary-color, #6c757d); + margin-right: 0.25rem; +} + +.ai-chat-messages .ai-code-copy-btn { + display: inline-flex; + align-items: center; + gap: 0.3rem; + padding: 0.2rem; + font-size: 0.8rem; + background: transparent; + border: none; + cursor: pointer; + color: var(--bs-secondary-color, #6c757d); + transition: color 0.15s; + white-space: nowrap; +} + +.ai-chat-messages .ai-code-copy-btn:hover { + color: var(--bs-body-color, #212529); +} + +.ai-chat-messages .ai-code-block pre { + margin: 0; + background: transparent !important; +} + +.ai-chat-messages .ai-code-block pre code.hljs { + background: transparent !important; + padding: 0.75rem 1rem 1rem; +} + +.ai-chat-messages pre code.hljs { + white-space: pre-wrap; + word-wrap: break-word; + overflow-wrap: break-word; + border-radius: 0.375rem; +} + +.ai-chat-doc-bar { + border-bottom: 1px solid var(--bs-border-color, #dee2e6); +} + +.ai-chat-drag-over { + outline: 2px dashed var(--bs-primary, #0d6efd) !important; + outline-offset: -2px; + background-color: rgba(13, 110, 253, 0.05) !important; +} + +.ai-chat-notification { + margin: 0.75rem 0 0.25rem; + padding: 0.625rem 0.875rem; + border-radius: 0.5rem; + border: 1px solid var(--bs-border-color, #dee2e6); + background-color: var(--bs-light, #f8f9fa); + font-size: 0.875rem; + line-height: 1.4; +} + +.ai-chat-notification-content { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.ai-chat-notification-icon { + flex-shrink: 0; + font-size: 1rem; + opacity: 0.8; +} + +.ai-chat-notification-text { + flex: 1; +} + +.ai-chat-notification-dismiss { + flex-shrink: 0; + opacity: 0.5; + transition: opacity 0.15s; +} + +.ai-chat-notification-dismiss:hover { + opacity: 1; +} + +.ai-chat-notification-actions { + display: flex; + gap: 0.375rem; + margin-top: 0.5rem; + padding-top: 0.5rem; + border-top: 1px solid var(--bs-border-color, #dee2e6); +} + +.ai-chat-notification-actions .btn { + font-size: 0.8125rem; + padding: 0.1875rem 0.625rem; +} + +.ai-chat-notification-typing { + border-color: var(--ai-chat-primary, #198754); + background-color: rgba(25, 135, 84, 0.05); +} + +.ai-chat-notification-typing .ai-chat-notification-icon { + color: var(--ai-chat-primary, #198754); + animation: ai-chat-typing-pulse 1.5s ease-in-out infinite; +} + +@keyframes ai-chat-typing-pulse { + 0%, 100% { opacity: 0.4; } + 50% { opacity: 1; } +} + +.ai-chat-notification-transfer { + border-color: var(--bs-warning, #ffc107); + background-color: rgba(255, 193, 7, 0.06); +} + +.ai-chat-notification-transfer .ai-chat-notification-icon { + color: var(--bs-warning, #ffc107); + animation: ai-chat-transfer-pulse 2s ease-in-out infinite; +} + +@keyframes ai-chat-transfer-pulse { + 0%, 100% { transform: scale(1); opacity: 0.7; } + 50% { transform: scale(1.1); opacity: 1; } +} + +.ai-chat-notification-ended, +.ai-chat-notification-session-ended, +.ai-chat-notification-conversation-ended { + border-color: var(--bs-secondary, #6c757d); + background-color: rgba(108, 117, 125, 0.05); +} + +.ai-chat-notification-ended .ai-chat-notification-icon, +.ai-chat-notification-session-ended .ai-chat-notification-icon, +.ai-chat-notification-conversation-ended .ai-chat-notification-icon { + color: var(--bs-secondary, #6c757d); +} + +.ai-chat-notification-info, +.ai-chat-notification-agent-connected { + border-color: var(--bs-info, #0dcaf0); + background-color: rgba(13, 202, 240, 0.05); +} + +.ai-chat-notification-info .ai-chat-notification-icon, +.ai-chat-notification-agent-connected .ai-chat-notification-icon { + color: var(--bs-info, #0dcaf0); +} + +.ai-chat-notification-warning, +.ai-chat-notification-agent-reconnecting { + border-color: var(--bs-warning, #ffc107); + background-color: rgba(255, 193, 7, 0.06); +} + +.ai-chat-notification-warning .ai-chat-notification-icon, +.ai-chat-notification-agent-reconnecting .ai-chat-notification-icon { + color: var(--bs-warning, #ffc107); +} + +.ai-chat-notification-error, +.ai-chat-notification-connection-lost { + border-color: var(--bs-danger, #dc3545); + background-color: rgba(220, 53, 69, 0.05); +} + +.ai-chat-notification-error .ai-chat-notification-icon, +.ai-chat-notification-connection-lost .ai-chat-notification-icon { + color: var(--bs-danger, #dc3545); +} + +/*# sourceMappingURL=ai-chat.css.map */ diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css.map b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css.map new file mode 100644 index 00000000..10bc064c --- /dev/null +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["ai-chat.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"ai-chat.css","sourcesContent":[".ai-chat-msg-role {\n font-size: 1.25rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n margin-bottom: 0.35rem;\n}\n\n.ai-chat-msg-role-user {\n color: var(--bs-primary, #0d6efd);\n}\n\n.ai-chat-msg-role-assistant {\n color: var(--ai-chat-primary, #198754);\n}\n\n.ai-chat-messages .ai-chat-message-item {\n position: relative;\n padding: 0.25rem 0;\n}\n\n.ai-chat-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin: 0.5rem auto 0.75rem;\n border-top: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-messages .ai-chat-message-item p:last-child {\n margin-bottom: 0;\n}\n\n.ai-chat-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-partial-transcript {\n font-style: italic;\n opacity: 0.7;\n}\n\n.ai-chat-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(255, 255, 255, 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n}\n\n.ai-chat-messages .message-buttons-container .tts-playing {\n color: var(--ai-chat-primary, #198754);\n}\n\n@keyframes spark-burst {\n 0% {\n transform: scale(1);\n opacity: 1;\n }\n 20% {\n transform: scale(1.8);\n opacity: 0.7;\n }\n 40% {\n transform: scale(0.9);\n opacity: 1;\n }\n 60% {\n transform: scale(1.3);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n.spark-effect i,\n.spark-effect svg {\n display: inline-block;\n animation: spark-burst 0.5s ease-out;\n}\n\n.ai-chat-messages .ai-bot-icon {\n color: currentColor;\n display: inline-block;\n animation: none;\n}\n\n@keyframes ai-chat-streaming-effect {\n 0% { opacity: 1; transform: rotate(0deg); }\n 10% { opacity: 0.3; transform: rotate(0deg); }\n 20% { opacity: 1; transform: rotate(0deg); }\n 30% { opacity: 0.3; transform: rotate(0deg); }\n 40% { opacity: 1; transform: rotate(0deg); }\n 50% { opacity: 0.3; transform: rotate(0deg); }\n 60% { opacity: 1; transform: rotate(0deg); }\n 80% { opacity: 1; transform: rotate(360deg); }\n 100% { opacity: 1; transform: rotate(360deg); }\n}\n\n.ai-chat-messages .ai-streaming-icon {\n color: currentColor;\n display: inline-block;\n animation: ai-chat-streaming-effect 4s ease-in-out infinite;\n}\n\n.ai-chat-messages pre {\n position: relative;\n margin: 0;\n}\n\n.ai-chat-messages .ai-code-block {\n border: 1px solid var(--bs-border-color, #dee2e6);\n border-radius: 0.5rem;\n overflow: hidden;\n margin: 0.75rem 0;\n background: var(--bs-body-bg, #fff);\n}\n\n.ai-chat-messages .ai-code-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n font-size: 0.8rem;\n min-height: 2rem;\n}\n\n.ai-chat-messages .ai-code-lang {\n font-weight: 600;\n color: var(--bs-body-color, #212529);\n text-transform: capitalize;\n}\n\n.ai-chat-messages .ai-code-lang i {\n color: var(--bs-secondary-color, #6c757d);\n margin-right: 0.25rem;\n}\n\n.ai-chat-messages .ai-code-copy-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0.2rem;\n font-size: 0.8rem;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--bs-secondary-color, #6c757d);\n transition: color 0.15s;\n white-space: nowrap;\n}\n\n.ai-chat-messages .ai-code-copy-btn:hover {\n color: var(--bs-body-color, #212529);\n}\n\n.ai-chat-messages .ai-code-block pre {\n margin: 0;\n background: transparent !important;\n}\n\n.ai-chat-messages .ai-code-block pre code.hljs {\n background: transparent !important;\n padding: 0.75rem 1rem 1rem;\n}\n\n.ai-chat-messages pre code.hljs {\n white-space: pre-wrap;\n word-wrap: break-word;\n overflow-wrap: break-word;\n border-radius: 0.375rem;\n}\n\n.ai-chat-doc-bar {\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-drag-over {\n outline: 2px dashed var(--bs-primary, #0d6efd) !important;\n outline-offset: -2px;\n background-color: rgba(13, 110, 253, 0.05) !important;\n}\n\n.ai-chat-notification {\n margin: 0.75rem 0 0.25rem;\n padding: 0.625rem 0.875rem;\n border-radius: 0.5rem;\n border: 1px solid var(--bs-border-color, #dee2e6);\n background-color: var(--bs-light, #f8f9fa);\n font-size: 0.875rem;\n line-height: 1.4;\n}\n\n.ai-chat-notification-content {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.ai-chat-notification-icon {\n flex-shrink: 0;\n font-size: 1rem;\n opacity: 0.8;\n}\n\n.ai-chat-notification-text {\n flex: 1;\n}\n\n.ai-chat-notification-dismiss {\n flex-shrink: 0;\n opacity: 0.5;\n transition: opacity 0.15s;\n}\n\n.ai-chat-notification-dismiss:hover {\n opacity: 1;\n}\n\n.ai-chat-notification-actions {\n display: flex;\n gap: 0.375rem;\n margin-top: 0.5rem;\n padding-top: 0.5rem;\n border-top: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-notification-actions .btn {\n font-size: 0.8125rem;\n padding: 0.1875rem 0.625rem;\n}\n\n.ai-chat-notification-typing {\n border-color: var(--ai-chat-primary, #198754);\n background-color: rgba(25, 135, 84, 0.05);\n}\n\n.ai-chat-notification-typing .ai-chat-notification-icon {\n color: var(--ai-chat-primary, #198754);\n animation: ai-chat-typing-pulse 1.5s ease-in-out infinite;\n}\n\n@keyframes ai-chat-typing-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n}\n\n.ai-chat-notification-transfer {\n border-color: var(--bs-warning, #ffc107);\n background-color: rgba(255, 193, 7, 0.06);\n}\n\n.ai-chat-notification-transfer .ai-chat-notification-icon {\n color: var(--bs-warning, #ffc107);\n animation: ai-chat-transfer-pulse 2s ease-in-out infinite;\n}\n\n@keyframes ai-chat-transfer-pulse {\n 0%, 100% { transform: scale(1); opacity: 0.7; }\n 50% { transform: scale(1.1); opacity: 1; }\n}\n\n.ai-chat-notification-ended,\n.ai-chat-notification-session-ended,\n.ai-chat-notification-conversation-ended {\n border-color: var(--bs-secondary, #6c757d);\n background-color: rgba(108, 117, 125, 0.05);\n}\n\n.ai-chat-notification-ended .ai-chat-notification-icon,\n.ai-chat-notification-session-ended .ai-chat-notification-icon,\n.ai-chat-notification-conversation-ended .ai-chat-notification-icon {\n color: var(--bs-secondary, #6c757d);\n}\n\n.ai-chat-notification-info,\n.ai-chat-notification-agent-connected {\n border-color: var(--bs-info, #0dcaf0);\n background-color: rgba(13, 202, 240, 0.05);\n}\n\n.ai-chat-notification-info .ai-chat-notification-icon,\n.ai-chat-notification-agent-connected .ai-chat-notification-icon {\n color: var(--bs-info, #0dcaf0);\n}\n\n.ai-chat-notification-warning,\n.ai-chat-notification-agent-reconnecting {\n border-color: var(--bs-warning, #ffc107);\n background-color: rgba(255, 193, 7, 0.06);\n}\n\n.ai-chat-notification-warning .ai-chat-notification-icon,\n.ai-chat-notification-agent-reconnecting .ai-chat-notification-icon {\n color: var(--bs-warning, #ffc107);\n}\n\n.ai-chat-notification-error,\n.ai-chat-notification-connection-lost {\n border-color: var(--bs-danger, #dc3545);\n background-color: rgba(220, 53, 69, 0.05);\n}\n\n.ai-chat-notification-error .ai-chat-notification-icon,\n.ai-chat-notification-connection-lost .ai-chat-notification-icon {\n color: var(--bs-danger, #dc3545);\n}\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.min.css b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.min.css new file mode 100644 index 00000000..d9fe2f23 --- /dev/null +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/ai-chat.min.css @@ -0,0 +1 @@ +.ai-chat-msg-role{font-size:1.25rem;font-weight:600;text-transform:uppercase;letter-spacing:.03em;margin-bottom:.35rem}.ai-chat-msg-role-user{color:var(--bs-primary,#0d6efd)}.ai-chat-msg-role-assistant{color:var(--ai-chat-primary,#198754)}.ai-chat-messages .ai-chat-message-item{position:relative;padding:.25rem 0}.ai-chat-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin:.5rem auto .75rem;border-top:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-messages .ai-chat-message-item p:last-child{margin-bottom:0}.ai-chat-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-partial-transcript{font-style:italic;opacity:.7}.ai-chat-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(255,255,255,.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(0,0,0,.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important}.ai-chat-messages .message-buttons-container .tts-playing{color:var(--ai-chat-primary,#198754)}@keyframes spark-burst{0%{transform:scale(1);opacity:1}20%{transform:scale(1.8);opacity:.7}40%{transform:scale(.9);opacity:1}60%{transform:scale(1.3)}100%{transform:scale(1)}}.spark-effect i,.spark-effect svg{display:inline-block;animation:spark-burst .5s ease-out}.ai-chat-messages .ai-bot-icon{color:currentColor;display:inline-block;animation:none}@keyframes ai-chat-streaming-effect{0%{opacity:1;transform:rotate(0)}10%{opacity:.3;transform:rotate(0)}20%{opacity:1;transform:rotate(0)}30%{opacity:.3;transform:rotate(0)}40%{opacity:1;transform:rotate(0)}50%{opacity:.3;transform:rotate(0)}60%{opacity:1;transform:rotate(0)}80%{opacity:1;transform:rotate(360deg)}100%{opacity:1;transform:rotate(360deg)}}.ai-chat-messages .ai-streaming-icon{color:currentColor;display:inline-block;animation:ai-chat-streaming-effect 4s ease-in-out infinite}.ai-chat-messages pre{position:relative;margin:0}.ai-chat-messages .ai-code-block{border:1px solid var(--bs-border-color,#dee2e6);border-radius:.5rem;overflow:hidden;margin:.75rem 0;background:var(--bs-body-bg,#fff)}.ai-chat-messages .ai-code-header{display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem;font-size:.8rem;min-height:2rem}.ai-chat-messages .ai-code-lang{font-weight:600;color:var(--bs-body-color,#212529);text-transform:capitalize}.ai-chat-messages .ai-code-lang i{color:var(--bs-secondary-color,#6c757d);margin-right:.25rem}.ai-chat-messages .ai-code-copy-btn{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem;font-size:.8rem;background:0 0;border:none;cursor:pointer;color:var(--bs-secondary-color,#6c757d);transition:color .15s;white-space:nowrap}.ai-chat-messages .ai-code-copy-btn:hover{color:var(--bs-body-color,#212529)}.ai-chat-messages .ai-code-block pre{margin:0;background:0 0!important}.ai-chat-messages .ai-code-block pre code.hljs{background:0 0!important;padding:.75rem 1rem 1rem}.ai-chat-messages pre code.hljs{white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;border-radius:.375rem}.ai-chat-doc-bar{border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-drag-over{outline:2px dashed var(--bs-primary,#0d6efd)!important;outline-offset:-2px;background-color:rgba(13,110,253,.05)!important}.ai-chat-notification{margin:.75rem 0 .25rem;padding:.625rem .875rem;border-radius:.5rem;border:1px solid var(--bs-border-color,#dee2e6);background-color:var(--bs-light,#f8f9fa);font-size:.875rem;line-height:1.4}.ai-chat-notification-content{display:flex;align-items:center;gap:.5rem}.ai-chat-notification-icon{flex-shrink:0;font-size:1rem;opacity:.8}.ai-chat-notification-text{flex:1}.ai-chat-notification-dismiss{flex-shrink:0;opacity:.5;transition:opacity .15s}.ai-chat-notification-dismiss:hover{opacity:1}.ai-chat-notification-actions{display:flex;gap:.375rem;margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-notification-actions .btn{font-size:.8125rem;padding:.1875rem .625rem}.ai-chat-notification-typing{border-color:var(--ai-chat-primary,#198754);background-color:rgba(25,135,84,.05)}.ai-chat-notification-typing .ai-chat-notification-icon{color:var(--ai-chat-primary,#198754);animation:ai-chat-typing-pulse 1.5s ease-in-out infinite}@keyframes ai-chat-typing-pulse{0%,100%{opacity:.4}50%{opacity:1}}.ai-chat-notification-transfer{border-color:var(--bs-warning,#ffc107);background-color:rgba(255,193,7,.06)}.ai-chat-notification-transfer .ai-chat-notification-icon{color:var(--bs-warning,#ffc107);animation:ai-chat-transfer-pulse 2s ease-in-out infinite}@keyframes ai-chat-transfer-pulse{0%,100%{transform:scale(1);opacity:.7}50%{transform:scale(1.1);opacity:1}}.ai-chat-notification-conversation-ended,.ai-chat-notification-ended,.ai-chat-notification-session-ended{border-color:var(--bs-secondary,#6c757d);background-color:rgba(108,117,125,.05)}.ai-chat-notification-conversation-ended .ai-chat-notification-icon,.ai-chat-notification-ended .ai-chat-notification-icon,.ai-chat-notification-session-ended .ai-chat-notification-icon{color:var(--bs-secondary,#6c757d)}.ai-chat-notification-agent-connected,.ai-chat-notification-info{border-color:var(--bs-info,#0dcaf0);background-color:rgba(13,202,240,.05)}.ai-chat-notification-agent-connected .ai-chat-notification-icon,.ai-chat-notification-info .ai-chat-notification-icon{color:var(--bs-info,#0dcaf0)}.ai-chat-notification-agent-reconnecting,.ai-chat-notification-warning{border-color:var(--bs-warning,#ffc107);background-color:rgba(255,193,7,.06)}.ai-chat-notification-agent-reconnecting .ai-chat-notification-icon,.ai-chat-notification-warning .ai-chat-notification-icon{color:var(--bs-warning,#ffc107)}.ai-chat-notification-connection-lost,.ai-chat-notification-error{border-color:var(--bs-danger,#dc3545);background-color:rgba(220,53,69,.05)}.ai-chat-notification-connection-lost .ai-chat-notification-icon,.ai-chat-notification-error .ai-chat-notification-icon{color:var(--bs-danger,#dc3545)} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css index 4a520ead..7eefca1e 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css @@ -160,7 +160,7 @@ } .ai-chat-widget-messages .ai-chat-msg-role-assistant { - color: #6f42c1; + color: var(--ai-widget-primary, #6f42c1); } .ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon { @@ -168,7 +168,7 @@ } .ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon { - color: #6f42c1; + color: currentColor; } .ai-chat-widget-messages .ai-chat-message-body { @@ -211,6 +211,11 @@ pointer-events: auto; } +.ai-chat-widget-messages .message-buttons-container:has(.tts-playing) { + opacity: 1; + pointer-events: auto; +} + .ai-chat-widget-messages .message-buttons-container > .button-message-toolbox { display: inline-flex; align-items: center; @@ -237,11 +242,76 @@ } .ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing { - color: var(--bs-primary, #0d6efd) !important; + color: var(--ai-widget-primary, #6f42c1) !important; opacity: 1; pointer-events: auto; } +.ai-chat-widget-history-panel { + position: absolute; + top: 3.5rem; + left: 0; + right: 0; + bottom: 0; + background: #fff; + padding: 1rem; + z-index: 10; + display: none; + overflow-y: auto; + flex-direction: column; +} + +.ai-chat-widget-history-panel.show { + display: flex; +} + +.ai-chat-widget-history-panel .history-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.75rem; + flex-shrink: 0; +} + +.ai-chat-widget-history-panel .history-header h5 { + margin: 0; + font-size: 1rem; +} + +.ai-chat-widget-history-list { + list-style: none; + padding: 0; + margin: 0; + overflow-y: auto; + flex: 1 1 auto; +} + +.ai-chat-widget-history-list li { + margin-bottom: 0; +} + +.ai-chat-widget-history-list .chat-session-history-item { + display: block; + padding: 0.5rem 0.75rem; + text-decoration: none; + color: var(--bs-body-color, #212529); + font-size: 0.85rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + transition: background 0.15s; + cursor: pointer; + border-bottom: 1px solid var(--bs-border-color, #dee2e6); +} + +.ai-chat-widget-history-list li:last-child .chat-session-history-item { + border-bottom: none; +} + +.ai-chat-widget-history-list .chat-session-history-item:hover { + background: var(--bs-tertiary-bg, #f8f9fa); +} + /* ── Notifications ── */ .ai-chat-widget-messages .ai-chat-notification { margin: 0.75rem 0.5rem 0; @@ -308,12 +378,20 @@ border-top: 1px solid #e9ecef; padding: 0.5rem 0.75rem; display: flex; + flex-wrap: wrap; gap: 0.5rem; align-items: flex-end; } +.ai-chat-widget-input .ai-chat-doc-bar { + flex: 0 0 100%; + margin: -0.5rem -0.75rem 0.5rem; + padding: 0.5rem 0.75rem; +} + .ai-chat-widget-input textarea { flex: 1; + min-width: 0; border: 1px solid #ced4da; border-radius: 8px; padding: 0.4rem 0.6rem; @@ -341,6 +419,29 @@ white-space: nowrap; } +.ai-chat-widget-input .btn { + background: var(--bs-body-bg, #fff); + color: var(--bs-body-color, #212529); + border: 1px solid var(--bs-border-color, #ced4da); +} + +.ai-chat-widget-input .btn.btn-link { + background: transparent; + color: var(--bs-secondary-color, #6c757d); + border: none; + padding: 0.4rem; +} + +.ai-chat-widget-input .btn.btn-outline-dark { + background: var(--bs-dark, #212529); + color: #fff; + border-color: var(--bs-dark, #212529); +} + +.ai-chat-widget-input .btn.btn-outline-secondary { + color: var(--bs-secondary-color, #6c757d); +} + .ai-chat-widget-input button:disabled { opacity: 0.5; cursor: not-allowed; diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css.map b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css.map index ea8d1efd..b36ed499 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css.map +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.css.map @@ -1 +1 @@ -{"version":3,"sources":["chat-widget.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"chat-widget.css","sourcesContent":["/* CrestApps AI Chat Widget */\n:root {\n --ai-widget-primary: var(--bs-secondary, #6c757d);\n --ai-widget-width: 380px;\n --ai-widget-height: 520px;\n}\n\n.ai-chat-widget-toggle {\n position: fixed;\n bottom: 1.25rem;\n right: 1.25rem;\n z-index: 10000;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ai-chat-widget-toggle:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 16px rgba(0,0,0,0.3);\n}\n\n.ai-chat-widget-container {\n position: fixed;\n bottom: 5rem;\n right: 1.25rem;\n z-index: 10001;\n width: var(--ai-widget-width);\n height: var(--ai-widget-height);\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.18);\n display: none;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ai-chat-widget-container.ai-chat-widget-resizable {\n resize: both;\n min-width: 320px;\n min-height: 420px;\n max-width: min(90vw, 960px);\n max-height: min(90vh, 960px);\n}\n\n.ai-chat-widget-container.open {\n display: flex;\n}\n\n.ai-chat-widget-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--ai-widget-primary);\n color: white;\n}\n\n.ai-chat-widget-header.ai-chat-widget-drag-handle {\n cursor: move;\n user-select: none;\n touch-action: none;\n}\n\n.ai-chat-widget-header-actions {\n display: flex;\n align-items: center;\n gap: 0.15rem;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-draggable {\n touch-action: none;\n}\n\n.ai-chat-widget-container.ai-chat-widget-dragging,\n.ai-chat-widget-toggle.ai-chat-widget-dragging {\n transition: none;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-dragging:hover {\n transform: none;\n}\n\n.ai-chat-widget-header .title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ai-chat-widget-header button {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n font-size: 1rem;\n padding: 0 0.25rem;\n opacity: 0.8;\n}\n\n.ai-chat-widget-header button:hover {\n opacity: 1;\n}\n\n.ai-chat-widget-profile-select {\n padding: 0.5rem 0.75rem;\n border-bottom: 1px solid #e9ecef;\n background: #f8f9fa;\n}\n\n.ai-chat-widget-profile-select select {\n width: 100%;\n padding: 0.35rem 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.ai-chat-widget-messages {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n font-size: 0.9rem;\n}\n\n/* ── Widget message items (ai-chat.js Vue template) ── */\n.ai-chat-widget-messages .ai-chat-messages {\n padding: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item {\n position: relative;\n padding: 0.5rem 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin-bottom: 0.5rem;\n border-top: 1px solid rgba(33, 37, 41, 0.08);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role {\n font-size: 0.7rem;\n font-weight: 600;\n margin-bottom: 2px;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-user {\n color: #0d6efd;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant {\n color: #6f42c1;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon {\n animation: ai-widget-pulse 1.5s infinite;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon {\n color: #6f42c1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body p:last-child {\n margin-bottom: 0;\n}\n\n/* ── Message action buttons (copy, thumbs up/down) ── */\n.ai-chat-widget-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(255, 255, 255, 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {\n color: var(--bs-primary, #0d6efd) !important;\n opacity: 1;\n pointer-events: auto;\n}\n\n/* ── Notifications ── */\n.ai-chat-widget-messages .ai-chat-notification {\n margin: 0.75rem 0.5rem 0;\n padding: 0.625rem 0.75rem;\n border: 1px solid rgba(33, 37, 41, 0.12);\n border-radius: 0.5rem;\n background: rgba(248, 249, 250, 0.98);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-content {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-icon {\n margin-top: 0.1rem;\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-dismiss {\n margin-left: auto !important;\n color: var(--bs-secondary-color, #6c757d) !important;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n\n/* ── Chart containers inside widget ── */\n.ai-chat-widget-messages .chart-container {\n width: 100%;\n max-width: 100% !important;\n min-height: 280px;\n}\n\n/* ── Code blocks & inline code ── */\n.ai-chat-widget-messages .ai-chat-message-body pre {\n background: #2d2d2d;\n color: #f8f8f2;\n padding: 0.5rem;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 0.8rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body code {\n font-size: 0.85em;\n}\n\n@keyframes ai-widget-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n.ai-chat-widget-input {\n border-top: 1px solid #e9ecef;\n padding: 0.5rem 0.75rem;\n display: flex;\n gap: 0.5rem;\n align-items: flex-end;\n}\n\n.ai-chat-widget-input textarea {\n flex: 1;\n border: 1px solid #ced4da;\n border-radius: 8px;\n padding: 0.4rem 0.6rem;\n font-size: 0.9rem;\n resize: none;\n max-height: 80px;\n min-height: 36px;\n line-height: 1.4;\n outline: none;\n}\n\n.ai-chat-widget-input textarea:focus {\n border-color: var(--ai-widget-primary);\n box-shadow: 0 0 0 2px rgba(65,182,112,0.15);\n}\n\n.ai-chat-widget-input button {\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n border-radius: 8px;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n font-size: 0.9rem;\n white-space: nowrap;\n}\n\n.ai-chat-widget-input button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ai-chat-widget-status {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n color: #6c757d;\n display: none;\n}\n\n.ai-chat-widget-status.visible {\n display: block;\n}\n\n.ai-chat-widget-welcome {\n text-align: center;\n color: #6c757d;\n padding: 2rem 1rem;\n font-size: 0.9rem;\n}\n\n@media (max-width: 576px) {\n .ai-chat-widget-container {\n width: calc(100vw - 1rem);\n height: calc(100vh - 6rem);\n right: 0.5rem;\n bottom: 4.5rem;\n }\n}\n"]} +{"version":3,"sources":["chat-widget.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"chat-widget.css","sourcesContent":["/* CrestApps AI Chat Widget */\n:root {\n --ai-widget-primary: var(--bs-secondary, #6c757d);\n --ai-widget-width: 380px;\n --ai-widget-height: 520px;\n}\n\n.ai-chat-widget-toggle {\n position: fixed;\n bottom: 1.25rem;\n right: 1.25rem;\n z-index: 10000;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ai-chat-widget-toggle:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 16px rgba(0,0,0,0.3);\n}\n\n.ai-chat-widget-container {\n position: fixed;\n bottom: 5rem;\n right: 1.25rem;\n z-index: 10001;\n width: var(--ai-widget-width);\n height: var(--ai-widget-height);\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.18);\n display: none;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ai-chat-widget-container.ai-chat-widget-resizable {\n resize: both;\n min-width: 320px;\n min-height: 420px;\n max-width: min(90vw, 960px);\n max-height: min(90vh, 960px);\n}\n\n.ai-chat-widget-container.open {\n display: flex;\n}\n\n.ai-chat-widget-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--ai-widget-primary);\n color: white;\n}\n\n.ai-chat-widget-header.ai-chat-widget-drag-handle {\n cursor: move;\n user-select: none;\n touch-action: none;\n}\n\n.ai-chat-widget-header-actions {\n display: flex;\n align-items: center;\n gap: 0.15rem;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-draggable {\n touch-action: none;\n}\n\n.ai-chat-widget-container.ai-chat-widget-dragging,\n.ai-chat-widget-toggle.ai-chat-widget-dragging {\n transition: none;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-dragging:hover {\n transform: none;\n}\n\n.ai-chat-widget-header .title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ai-chat-widget-header button {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n font-size: 1rem;\n padding: 0 0.25rem;\n opacity: 0.8;\n}\n\n.ai-chat-widget-header button:hover {\n opacity: 1;\n}\n\n.ai-chat-widget-profile-select {\n padding: 0.5rem 0.75rem;\n border-bottom: 1px solid #e9ecef;\n background: #f8f9fa;\n}\n\n.ai-chat-widget-profile-select select {\n width: 100%;\n padding: 0.35rem 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.ai-chat-widget-messages {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n font-size: 0.9rem;\n}\n\n/* ── Widget message items (ai-chat.js Vue template) ── */\n.ai-chat-widget-messages .ai-chat-messages {\n padding: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item {\n position: relative;\n padding: 0.5rem 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin-bottom: 0.5rem;\n border-top: 1px solid rgba(33, 37, 41, 0.08);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role {\n font-size: 0.7rem;\n font-weight: 600;\n margin-bottom: 2px;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-user {\n color: #0d6efd;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant {\n color: var(--ai-widget-primary, #6f42c1);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon {\n animation: ai-widget-pulse 1.5s infinite;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon {\n color: currentColor;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body p:last-child {\n margin-bottom: 0;\n}\n\n/* ── Message action buttons (copy, thumbs up/down) ── */\n.ai-chat-widget-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(255, 255, 255, 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {\n color: var(--ai-widget-primary, #6f42c1) !important;\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-history-panel {\n position: absolute;\n top: 3.5rem;\n left: 0;\n right: 0;\n bottom: 0;\n background: #fff;\n padding: 1rem;\n z-index: 10;\n display: none;\n overflow-y: auto;\n flex-direction: column;\n}\n\n.ai-chat-widget-history-panel.show {\n display: flex;\n}\n\n.ai-chat-widget-history-panel .history-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n flex-shrink: 0;\n}\n\n.ai-chat-widget-history-panel .history-header h5 {\n margin: 0;\n font-size: 1rem;\n}\n\n.ai-chat-widget-history-list {\n list-style: none;\n padding: 0;\n margin: 0;\n overflow-y: auto;\n flex: 1 1 auto;\n}\n\n.ai-chat-widget-history-list li {\n margin-bottom: 0;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item {\n display: block;\n padding: 0.5rem 0.75rem;\n text-decoration: none;\n color: var(--bs-body-color, #212529);\n font-size: 0.85rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: background 0.15s;\n cursor: pointer;\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-widget-history-list li:last-child .chat-session-history-item {\n border-bottom: none;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item:hover {\n background: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n/* ── Notifications ── */\n.ai-chat-widget-messages .ai-chat-notification {\n margin: 0.75rem 0.5rem 0;\n padding: 0.625rem 0.75rem;\n border: 1px solid rgba(33, 37, 41, 0.12);\n border-radius: 0.5rem;\n background: rgba(248, 249, 250, 0.98);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-content {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-icon {\n margin-top: 0.1rem;\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-dismiss {\n margin-left: auto !important;\n color: var(--bs-secondary-color, #6c757d) !important;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n\n/* ── Chart containers inside widget ── */\n.ai-chat-widget-messages .chart-container {\n width: 100%;\n max-width: 100% !important;\n min-height: 280px;\n}\n\n/* ── Code blocks & inline code ── */\n.ai-chat-widget-messages .ai-chat-message-body pre {\n background: #2d2d2d;\n color: #f8f8f2;\n padding: 0.5rem;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 0.8rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body code {\n font-size: 0.85em;\n}\n\n@keyframes ai-widget-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n.ai-chat-widget-input {\n border-top: 1px solid #e9ecef;\n padding: 0.5rem 0.75rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: flex-end;\n}\n\n.ai-chat-widget-input .ai-chat-doc-bar {\n flex: 0 0 100%;\n margin: -0.5rem -0.75rem 0.5rem;\n padding: 0.5rem 0.75rem;\n}\n\n.ai-chat-widget-input textarea {\n flex: 1;\n min-width: 0;\n border: 1px solid #ced4da;\n border-radius: 8px;\n padding: 0.4rem 0.6rem;\n font-size: 0.9rem;\n resize: none;\n max-height: 80px;\n min-height: 36px;\n line-height: 1.4;\n outline: none;\n}\n\n.ai-chat-widget-input textarea:focus {\n border-color: var(--ai-widget-primary);\n box-shadow: 0 0 0 2px rgba(65,182,112,0.15);\n}\n\n.ai-chat-widget-input button {\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n border-radius: 8px;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n font-size: 0.9rem;\n white-space: nowrap;\n}\n\n.ai-chat-widget-input .btn {\n background: var(--bs-body-bg, #fff);\n color: var(--bs-body-color, #212529);\n border: 1px solid var(--bs-border-color, #ced4da);\n}\n\n.ai-chat-widget-input .btn.btn-link {\n background: transparent;\n color: var(--bs-secondary-color, #6c757d);\n border: none;\n padding: 0.4rem;\n}\n\n.ai-chat-widget-input .btn.btn-outline-dark {\n background: var(--bs-dark, #212529);\n color: #fff;\n border-color: var(--bs-dark, #212529);\n}\n\n.ai-chat-widget-input .btn.btn-outline-secondary {\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-input button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ai-chat-widget-status {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n color: #6c757d;\n display: none;\n}\n\n.ai-chat-widget-status.visible {\n display: block;\n}\n\n.ai-chat-widget-welcome {\n text-align: center;\n color: #6c757d;\n padding: 2rem 1rem;\n font-size: 0.9rem;\n}\n\n@media (max-width: 576px) {\n .ai-chat-widget-container {\n width: calc(100vw - 1rem);\n height: calc(100vh - 6rem);\n right: 0.5rem;\n bottom: 4.5rem;\n }\n}\n"]} diff --git a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.min.css b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.min.css index f1584463..47205d3a 100644 --- a/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.min.css +++ b/src/Resources/CrestApps.AI.Resources/wwwroot/styles/chat-widget.min.css @@ -1 +1 @@ -:root{--ai-widget-primary:var(--bs-secondary, #6c757d);--ai-widget-width:380px;--ai-widget-height:520px}.ai-chat-widget-toggle{position:fixed;bottom:1.25rem;right:1.25rem;z-index:10000;width:52px;height:52px;border-radius:50%;background:var(--ai-widget-primary);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;box-shadow:0 4px 12px rgba(0,0,0,.2);transition:transform .2s,box-shadow .2s}.ai-chat-widget-toggle:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(0,0,0,.3)}.ai-chat-widget-container{position:fixed;bottom:5rem;right:1.25rem;z-index:10001;width:var(--ai-widget-width);height:var(--ai-widget-height);background:#fff;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.18);display:none;flex-direction:column;overflow:hidden}.ai-chat-widget-container.ai-chat-widget-resizable{resize:both;min-width:320px;min-height:420px;max-width:min(90vw,960px);max-height:min(90vh,960px)}.ai-chat-widget-container.open{display:flex}.ai-chat-widget-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--ai-widget-primary);color:#fff}.ai-chat-widget-header.ai-chat-widget-drag-handle{cursor:move;user-select:none;touch-action:none}.ai-chat-widget-header-actions{display:flex;align-items:center;gap:.15rem}.ai-chat-widget-toggle.ai-chat-widget-draggable{touch-action:none}.ai-chat-widget-container.ai-chat-widget-dragging,.ai-chat-widget-toggle.ai-chat-widget-dragging{transition:none}.ai-chat-widget-toggle.ai-chat-widget-dragging:hover{transform:none}.ai-chat-widget-header .title{font-weight:600;font-size:.95rem}.ai-chat-widget-header button{background:0 0;border:none;color:#fff;cursor:pointer;font-size:1rem;padding:0 .25rem;opacity:.8}.ai-chat-widget-header button:hover{opacity:1}.ai-chat-widget-profile-select{padding:.5rem .75rem;border-bottom:1px solid #e9ecef;background:#f8f9fa}.ai-chat-widget-profile-select select{width:100%;padding:.35rem .5rem;border:1px solid #ced4da;border-radius:6px;font-size:.85rem}.ai-chat-widget-messages{flex:1;overflow-y:auto;padding:.75rem;font-size:.9rem}.ai-chat-widget-messages .ai-chat-messages{padding:.5rem}.ai-chat-widget-messages .ai-chat-message-item{position:relative;padding:.5rem 0}.ai-chat-widget-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin-bottom:.5rem;border-top:1px solid rgba(33,37,41,.08)}.ai-chat-widget-messages .ai-chat-msg-role{font-size:.7rem;font-weight:600;margin-bottom:2px}.ai-chat-widget-messages .ai-chat-msg-role-user{color:#0d6efd}.ai-chat-widget-messages .ai-chat-msg-role-assistant{color:#6f42c1}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon{animation:ai-widget-pulse 1.5s infinite}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon{color:#6f42c1}.ai-chat-widget-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-widget-messages .ai-chat-message-body p:last-child{margin-bottom:0}.ai-chat-widget-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(255,255,255,.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(0,0,0,.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.tts-playing{color:var(--bs-primary,#0d6efd)!important;opacity:1;pointer-events:auto}.ai-chat-widget-messages .ai-chat-notification{margin:.75rem .5rem 0;padding:.625rem .75rem;border:1px solid rgba(33,37,41,.12);border-radius:.5rem;background:rgba(248,249,250,.98)}.ai-chat-widget-messages .ai-chat-notification-content{display:flex;align-items:flex-start;gap:.5rem}.ai-chat-widget-messages .ai-chat-notification-icon{margin-top:.1rem;color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-messages .ai-chat-notification-text{flex:1 1 auto;min-width:0}.ai-chat-widget-messages .ai-chat-notification-dismiss{margin-left:auto!important;color:var(--bs-secondary-color,#6c757d)!important}.ai-chat-widget-messages .ai-chat-notification-actions{display:flex;gap:.5rem;margin-top:.5rem}.ai-chat-widget-messages .chart-container{width:100%;max-width:100%!important;min-height:280px}.ai-chat-widget-messages .ai-chat-message-body pre{background:#2d2d2d;color:#f8f8f2;padding:.5rem;border-radius:4px;overflow-x:auto;font-size:.8rem}.ai-chat-widget-messages .ai-chat-message-body code{font-size:.85em}@keyframes ai-widget-pulse{0%,100%{opacity:1}50%{opacity:.4}}.ai-chat-widget-input{border-top:1px solid #e9ecef;padding:.5rem .75rem;display:flex;gap:.5rem;align-items:flex-end}.ai-chat-widget-input textarea{flex:1;border:1px solid #ced4da;border-radius:8px;padding:.4rem .6rem;font-size:.9rem;resize:none;max-height:80px;min-height:36px;line-height:1.4;outline:0}.ai-chat-widget-input textarea:focus{border-color:var(--ai-widget-primary);box-shadow:0 0 0 2px rgba(65,182,112,.15)}.ai-chat-widget-input button{background:var(--ai-widget-primary);color:#fff;border:none;border-radius:8px;padding:.4rem .75rem;cursor:pointer;font-size:.9rem;white-space:nowrap}.ai-chat-widget-input button:disabled{opacity:.5;cursor:not-allowed}.ai-chat-widget-status{padding:.25rem .75rem;font-size:.8rem;color:#6c757d;display:none}.ai-chat-widget-status.visible{display:block}.ai-chat-widget-welcome{text-align:center;color:#6c757d;padding:2rem 1rem;font-size:.9rem}@media (max-width:576px){.ai-chat-widget-container{width:calc(100vw - 1rem);height:calc(100vh - 6rem);right:.5rem;bottom:4.5rem}} +:root{--ai-widget-primary:var(--bs-secondary, #6c757d);--ai-widget-width:380px;--ai-widget-height:520px}.ai-chat-widget-toggle{position:fixed;bottom:1.25rem;right:1.25rem;z-index:10000;width:52px;height:52px;border-radius:50%;background:var(--ai-widget-primary);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;box-shadow:0 4px 12px rgba(0,0,0,.2);transition:transform .2s,box-shadow .2s}.ai-chat-widget-toggle:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(0,0,0,.3)}.ai-chat-widget-container{position:fixed;bottom:5rem;right:1.25rem;z-index:10001;width:var(--ai-widget-width);height:var(--ai-widget-height);background:#fff;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.18);display:none;flex-direction:column;overflow:hidden}.ai-chat-widget-container.ai-chat-widget-resizable{resize:both;min-width:320px;min-height:420px;max-width:min(90vw,960px);max-height:min(90vh,960px)}.ai-chat-widget-container.open{display:flex}.ai-chat-widget-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--ai-widget-primary);color:#fff}.ai-chat-widget-header.ai-chat-widget-drag-handle{cursor:move;user-select:none;touch-action:none}.ai-chat-widget-header-actions{display:flex;align-items:center;gap:.15rem}.ai-chat-widget-toggle.ai-chat-widget-draggable{touch-action:none}.ai-chat-widget-container.ai-chat-widget-dragging,.ai-chat-widget-toggle.ai-chat-widget-dragging{transition:none}.ai-chat-widget-toggle.ai-chat-widget-dragging:hover{transform:none}.ai-chat-widget-header .title{font-weight:600;font-size:.95rem}.ai-chat-widget-header button{background:0 0;border:none;color:#fff;cursor:pointer;font-size:1rem;padding:0 .25rem;opacity:.8}.ai-chat-widget-header button:hover{opacity:1}.ai-chat-widget-profile-select{padding:.5rem .75rem;border-bottom:1px solid #e9ecef;background:#f8f9fa}.ai-chat-widget-profile-select select{width:100%;padding:.35rem .5rem;border:1px solid #ced4da;border-radius:6px;font-size:.85rem}.ai-chat-widget-messages{flex:1;overflow-y:auto;padding:.75rem;font-size:.9rem}.ai-chat-widget-messages .ai-chat-messages{padding:.5rem}.ai-chat-widget-messages .ai-chat-message-item{position:relative;padding:.5rem 0}.ai-chat-widget-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin-bottom:.5rem;border-top:1px solid rgba(33,37,41,.08)}.ai-chat-widget-messages .ai-chat-msg-role{font-size:.7rem;font-weight:600;margin-bottom:2px}.ai-chat-widget-messages .ai-chat-msg-role-user{color:#0d6efd}.ai-chat-widget-messages .ai-chat-msg-role-assistant{color:var(--ai-widget-primary,#6f42c1)}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon{animation:ai-widget-pulse 1.5s infinite}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon{color:currentColor}.ai-chat-widget-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-widget-messages .ai-chat-message-body p:last-child{margin-bottom:0}.ai-chat-widget-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(255,255,255,.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(0,0,0,.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.tts-playing{color:var(--ai-widget-primary,#6f42c1)!important;opacity:1;pointer-events:auto}.ai-chat-widget-history-panel{position:absolute;top:3.5rem;left:0;right:0;bottom:0;background:#fff;padding:1rem;z-index:10;display:none;overflow-y:auto;flex-direction:column}.ai-chat-widget-history-panel.show{display:flex}.ai-chat-widget-history-panel .history-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem;flex-shrink:0}.ai-chat-widget-history-panel .history-header h5{margin:0;font-size:1rem}.ai-chat-widget-history-list{list-style:none;padding:0;margin:0;overflow-y:auto;flex:1 1 auto}.ai-chat-widget-history-list li{margin-bottom:0}.ai-chat-widget-history-list .chat-session-history-item{display:block;padding:.5rem .75rem;text-decoration:none;color:var(--bs-body-color,#212529);font-size:.85rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .15s;cursor:pointer;border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-widget-history-list li:last-child .chat-session-history-item{border-bottom:none}.ai-chat-widget-history-list .chat-session-history-item:hover{background:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-messages .ai-chat-notification{margin:.75rem .5rem 0;padding:.625rem .75rem;border:1px solid rgba(33,37,41,.12);border-radius:.5rem;background:rgba(248,249,250,.98)}.ai-chat-widget-messages .ai-chat-notification-content{display:flex;align-items:flex-start;gap:.5rem}.ai-chat-widget-messages .ai-chat-notification-icon{margin-top:.1rem;color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-messages .ai-chat-notification-text{flex:1 1 auto;min-width:0}.ai-chat-widget-messages .ai-chat-notification-dismiss{margin-left:auto!important;color:var(--bs-secondary-color,#6c757d)!important}.ai-chat-widget-messages .ai-chat-notification-actions{display:flex;gap:.5rem;margin-top:.5rem}.ai-chat-widget-messages .chart-container{width:100%;max-width:100%!important;min-height:280px}.ai-chat-widget-messages .ai-chat-message-body pre{background:#2d2d2d;color:#f8f8f2;padding:.5rem;border-radius:4px;overflow-x:auto;font-size:.8rem}.ai-chat-widget-messages .ai-chat-message-body code{font-size:.85em}@keyframes ai-widget-pulse{0%,100%{opacity:1}50%{opacity:.4}}.ai-chat-widget-input{border-top:1px solid #e9ecef;padding:.5rem .75rem;display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-end}.ai-chat-widget-input .ai-chat-doc-bar{flex:0 0 100%;margin:-.5rem -.75rem .5rem;padding:.5rem .75rem}.ai-chat-widget-input textarea{flex:1;min-width:0;border:1px solid #ced4da;border-radius:8px;padding:.4rem .6rem;font-size:.9rem;resize:none;max-height:80px;min-height:36px;line-height:1.4;outline:0}.ai-chat-widget-input textarea:focus{border-color:var(--ai-widget-primary);box-shadow:0 0 0 2px rgba(65,182,112,.15)}.ai-chat-widget-input button{background:var(--ai-widget-primary);color:#fff;border:none;border-radius:8px;padding:.4rem .75rem;cursor:pointer;font-size:.9rem;white-space:nowrap}.ai-chat-widget-input .btn{background:var(--bs-body-bg,#fff);color:var(--bs-body-color,#212529);border:1px solid var(--bs-border-color,#ced4da)}.ai-chat-widget-input .btn.btn-link{background:0 0;color:var(--bs-secondary-color,#6c757d);border:none;padding:.4rem}.ai-chat-widget-input .btn.btn-outline-dark{background:var(--bs-dark,#212529);color:#fff;border-color:var(--bs-dark,#212529)}.ai-chat-widget-input .btn.btn-outline-secondary{color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-input button:disabled{opacity:.5;cursor:not-allowed}.ai-chat-widget-status{padding:.25rem .75rem;font-size:.8rem;color:#6c757d;display:none}.ai-chat-widget-status.visible{display:block}.ai-chat-widget-welcome{text-align:center;color:#6c757d;padding:2rem 1rem;font-size:.9rem}@media (max-width:576px){.ai-chat-widget-container{width:calc(100vw - 1rem);height:calc(100vh - 6rem);right:.5rem;bottom:4.5rem}} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/A2A/Controllers/A2AConnectionController.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/A2A/Controllers/A2AConnectionController.cs index 1d8875ec..e2a9e3ed 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/A2A/Controllers/A2AConnectionController.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/A2A/Controllers/A2AConnectionController.cs @@ -269,4 +269,4 @@ private static string ProtectOrReuse(string value, string existingProtectedValue return existingProtectedValue; } -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AI/ViewModels/AIConnectionViewModel.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AI/ViewModels/AIConnectionViewModel.cs index 0dfccac1..b6f13f1d 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AI/ViewModels/AIConnectionViewModel.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AI/ViewModels/AIConnectionViewModel.cs @@ -86,4 +86,4 @@ public void ApplyTo(AIProviderConnection connection) connection.Properties.Remove("AuthenticationType"); } } -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/BackgroundServices/AIChatSessionCloseBackgroundService.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/BackgroundServices/AIChatSessionCloseBackgroundService.cs index 1f642203..ee34b2c6 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/BackgroundServices/AIChatSessionCloseBackgroundService.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/BackgroundServices/AIChatSessionCloseBackgroundService.cs @@ -8,7 +8,6 @@ namespace CrestApps.Core.Mvc.Web.Areas.AIChat.BackgroundServices; - /// /// Periodically closes inactive AI chat sessions and marks them for post-session processing. /// Mirrors the behavior of Orchard Core's AIChatSessionCloseBackgroundTask. diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Controllers/ChatExtractedDataController.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Controllers/ChatExtractedDataController.cs index dc5aeb3e..911782a4 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Controllers/ChatExtractedDataController.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Controllers/ChatExtractedDataController.cs @@ -125,4 +125,4 @@ private static string EscapeCsv(string value) return value; } -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Controllers/UsageAnalyticsController.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Controllers/UsageAnalyticsController.cs index 7b810a4d..7b1f4e6f 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Controllers/UsageAnalyticsController.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Controllers/UsageAnalyticsController.cs @@ -78,4 +78,4 @@ private static string GetUserLabel(AICompletionUsageRecord record) return "Anonymous"; } -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Views/Shared/_ChatWidget.cshtml b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Views/Shared/_ChatWidget.cshtml index a262d778..e5315ebc 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Views/Shared/_ChatWidget.cshtml +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/AIChat/Views/Shared/_ChatWidget.cshtml @@ -12,18 +12,28 @@ @{ var adminWidgetSettings = SiteSettings.Get(); var defaultDeploymentSettings = SiteSettings.Get(); + var selectedProfile = string.IsNullOrWhiteSpace(adminWidgetSettings.ProfileId) ? null : await ProfileManager.FindByIdAsync(adminWidgetSettings.ProfileId); - ChatModeProfileSettings profileChatModeSettings = null; - if (selectedProfile is not null) + + var configuredChatMode = ChatMode.TextInput; + var hasTtsDeployment = !string.IsNullOrWhiteSpace(defaultDeploymentSettings.DefaultTextToSpeechDeploymentName); + var textToSpeechEnabled = false; + var ttsVoiceName = defaultDeploymentSettings.DefaultTextToSpeechVoiceId; + + if (selectedProfile?.TryGetSettings(out var profileChatModeSettings) == true) { - selectedProfile.TryGetSettings(out profileChatModeSettings); + configuredChatMode = profileChatModeSettings.ChatMode; + textToSpeechEnabled = (profileChatModeSettings?.EnableTextToSpeechPlayback ?? false) && hasTtsDeployment; + + if (!string.IsNullOrEmpty(profileChatModeSettings?.VoiceName)) + { + ttsVoiceName = profileChatModeSettings.VoiceName; + } } - var configuredChatMode = profileChatModeSettings?.ChatMode ?? ChatMode.TextInput; + var speechToTextEnabled = !string.IsNullOrWhiteSpace(defaultDeploymentSettings.DefaultSpeechToTextDeploymentName); - var hasTtsDeployment = !string.IsNullOrWhiteSpace(defaultDeploymentSettings.DefaultTextToSpeechDeploymentName); - var textToSpeechEnabled = (profileChatModeSettings?.EnableTextToSpeechPlayback ?? false) && hasTtsDeployment; var effectiveChatMode = configuredChatMode switch { ChatMode.Conversation when speechToTextEnabled && hasTtsDeployment => ChatMode.Conversation, @@ -31,6 +41,7 @@ ChatMode.Conversation when speechToTextEnabled => ChatMode.AudioInput, _ => ChatMode.TextInput, }; + var supportedExtensionsAccept = ChatDocumentOptions.Value.GetAllowedFileExtensionsAcceptValue(); var supportedExtensionsDisplay = ChatDocumentOptions.Value.GetAllowedFileExtensionsDisplayValue(); var profile = selectedProfile is null || selectedProfile.Type != AIProfileType.Chat @@ -38,7 +49,7 @@ : new { chatMode = effectiveChatMode.ToString(), - ttsVoiceName = profileChatModeSettings?.VoiceName ?? defaultDeploymentSettings.DefaultTextToSpeechVoiceId, + ttsVoiceName = ttsVoiceName, id = selectedProfile.ItemId, name = selectedProfile.Name, displayText = selectedProfile.DisplayText ?? selectedProfile.Name, @@ -46,173 +57,340 @@ enableSessionMetrics = selectedProfile.TryGet(out var analyticsMetadata) && analyticsMetadata.EnableSessionMetrics, allowSessionDocuments = selectedProfile.TryGet(out var sessionDocMetadata) && sessionDocMetadata.AllowSessionDocuments, }; + + if (profile == null) + { + return; + } + var widgetStyle = string.IsNullOrWhiteSpace(adminWidgetSettings.PrimaryColor) ? null : $"--ai-widget-primary: {adminWidgetSettings.PrimaryColor.Trim()};"; + var widgetShellStyle = string.IsNullOrWhiteSpace(widgetStyle) + ? "visibility:hidden;" + : $"{widgetStyle}visibility:hidden;"; } +
+ + -@if (profile != null) -{ -
- - - - - - - -
-
- AI Chat -
- - - -
+ + + + +
+
+ AI Chat +
+ + +
+
-
-
-
-
- @(string.IsNullOrWhiteSpace(profile.welcomeMessage) ? "What do you want to know?" : profile.welcomeMessage) -
+
+
+
+
+ @(string.IsNullOrWhiteSpace(profile.welcomeMessage) ? "What do you want to know?" : profile.welcomeMessage)
-
+
+
-
+
-
- - + @if (profile.chatMode == nameof(ChatMode.Conversation)) + { + - @if (profile.chatMode == nameof(ChatMode.Conversation)) - { - - } - -
+ } +
+
- - - - - - - - - - setPlaceholder(selectedProfile); - chatInput.setAttribute('data-profile-id', selectedProfile.id); - - var widgetApp = window.openAIChatManager.initialize({ - signalRHubUrl: '/hubs/ai-chat', - appElementSelector: '#widget-chat-app', - chatContainerElementSelector: '#widget-chat-container', - inputElementSelector: '#widget-chat-input', - sendButtonElementSelector: '#widget-send-btn', - placeholderElementSelector: '#widget-placeholder', - messages: [], - autoCreateSession: true, - metricsEnabled: selectedProfile.enableSessionMetrics, - chatMode: selectedProfile.chatMode, - micButtonElementSelector: '#widget-mic-btn', - conversationButtonElementSelector: '#widget-conversation-btn', - ttsVoiceName: selectedProfile.ttsVoiceName || null, - sessionDocumentsEnabled: selectedProfile.allowSessionDocuments, - existingDocuments: [], - documentBarSelector: '#widget-chat-document-bar', - uploadDocumentUrl: '@Url.Content("~/ai/chat-sessions/upload-document")', - removeDocumentUrl: '@Url.Content("~/ai/chat-sessions/remove-document")', - allowedExtensions: @Html.Raw(System.Text.Json.JsonSerializer.Serialize(supportedExtensionsAccept)), - supportedExtensionsText: @Html.Raw(System.Text.Json.JsonSerializer.Serialize(supportedExtensionsDisplay)), - widget: { - chatWidgetContainer: '#widget-panel', - chatWidgetStateName: widgetStateName, - toggleButtonSelector: '#widget-toggle', - resetSizeButtonSelector: '#widget-reset-size', - enableDragging: true, - enableResizing: true, - persistLayout: true - } - }); + + + + + + + + -
-} + function syncOpenPanelPosition() { + if (!widgetApp) { + return; + } + + if (typeof widgetApp.syncPanelPositionToToggle === 'function') { + widgetApp.syncPanelPositionToToggle(false); + } + } + + function revealShellWhenStable(initialOpen) { + if (!shell || shell.dataset.deferReveal !== 'true' || !initialOpen) { + revealShell(); + return; + } + + var hasRevealed = false; + var resizeObserver = null; + + function finalizeReveal() { + if (hasRevealed) { + return; + } + + hasRevealed = true; + + if (resizeObserver) { + resizeObserver.disconnect(); + } + + requestAnimationFrame(function () { + syncOpenPanelPosition(); + requestAnimationFrame(function () { + revealShell(); + }); + }); + } + + if (typeof ResizeObserver === 'undefined') { + window.setTimeout(finalizeReveal, 0); + return; + } + + var lastWidth = 0; + var lastHeight = 0; + var stablePasses = 0; + + resizeObserver = new ResizeObserver(function (entries) { + var entry = entries && entries[0]; + + if (!entry) { + return; + } + + var width = Math.round(entry.contentRect.width); + var height = Math.round(entry.contentRect.height); + + if (!width || !height) { + return; + } + + syncOpenPanelPosition(); + + if (width === lastWidth && height === lastHeight) { + stablePasses++; + } else { + lastWidth = width; + lastHeight = height; + stablePasses = 0; + } + + if (stablePasses >= 1) { + finalizeReveal(); + } + }); + + resizeObserver.observe(panel); + + window.setTimeout(finalizeReveal, 150); + } + + function setPlaceholder(profile) { + if (!placeholder) { + return; + } + + var welcome = profile && profile.welcomeMessage ? profile.welcomeMessage : 'What do you want to know?'; + placeholder.innerHTML = '

' + welcome + '
'; + } + + function setPanelOpen(isOpen) { + if (widgetApp) { + var isCurrentlyOpen = panel.classList.contains('open'); + if (isOpen && !isCurrentlyOpen && typeof widgetApp.syncPanelPositionToToggle === 'function') { + widgetApp.syncPanelPositionToToggle(); + } else if (!isOpen && isCurrentlyOpen && typeof widgetApp.syncTogglePositionToPanel === 'function') { + widgetApp.syncTogglePositionToPanel(); + } + } + panel.classList.toggle('open', isOpen); + panel.style.display = isOpen ? 'flex' : 'none'; + panel.setAttribute('aria-hidden', isOpen ? 'false' : 'true'); + toggle.innerHTML = isOpen + ? '' + : ''; + localStorage.setItem(widgetOpenStateKey, isOpen ? 'true' : 'false'); + + // When the panel becomes visible, render any charts that were + // deferred because the canvas had zero dimensions while hidden. + if (isOpen && typeof window.renderPendingCharts === 'function') { + setTimeout(function () { window.renderPendingCharts(); }, 100); + } + } + + setPlaceholder(selectedProfile); + chatInput.setAttribute('data-profile-id', selectedProfile.id); + + var widgetApp = window.openAIChatManager.initialize({ + signalRHubUrl: '/hubs/ai-chat', + appElementSelector: '#widget-chat-app', + chatContainerElementSelector: '#widget-chat-container', + inputElementSelector: '#widget-chat-input', + sendButtonElementSelector: '#widget-send-btn', + placeholderElementSelector: '#widget-placeholder', + messages: [], + autoCreateSession: true, + metricsEnabled: selectedProfile.enableSessionMetrics, + chatMode: selectedProfile.chatMode, + micButtonElementSelector: '#widget-mic-btn', + conversationButtonElementSelector: '#widget-conversation-btn', + ttsVoiceName: selectedProfile.ttsVoiceName || null, + sessionDocumentsEnabled: selectedProfile.allowSessionDocuments, + existingDocuments: [], + documentBarSelector: '#widget-chat-document-bar', + uploadDocumentUrl: '@Url.Content("~/ai/chat-sessions/upload-document")', + removeDocumentUrl: '@Url.Content("~/ai/chat-sessions/remove-document")', + allowedExtensions: @Html.Raw(System.Text.Json.JsonSerializer.Serialize(supportedExtensionsAccept)), + supportedExtensionsText: @Html.Raw(System.Text.Json.JsonSerializer.Serialize(supportedExtensionsDisplay)), + widget: { + chatWidgetContainer: '#widget-panel', + chatWidgetStateName: widgetStateName, + toggleButtonSelector: '#widget-toggle', + resetSizeButtonSelector: '#widget-reset-size', + enableDragging: true, + enableResizing: true, + persistLayout: true + } + }); + + widgetApp.metricsEnabled = !!selectedProfile.enableSessionMetrics; + + var initialOpen = shell && shell.dataset.initialOpen === 'true'; + setPanelOpen(initialOpen); + revealShellWhenStable(initialOpen); + + toggle.addEventListener('click', function () { + if (toggle.dataset.dragSuppressClick === 'true') { + toggle.dataset.dragSuppressClick = 'false'; + return; + } + setPanelOpen(!panel.classList.contains('open')); + }); + + closeBtn.addEventListener('click', function () { + setPanelOpen(false); + }); + + newChatBtn.addEventListener('click', function () { + setPlaceholder(selectedProfile); + widgetApp.resetSession(); + }); + }); + +
diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Admin/Handlers/ArticleIndexProfileHandler.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Admin/Handlers/ArticleIndexProfileHandler.cs index 33d1f4d7..8656cec4 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Admin/Handlers/ArticleIndexProfileHandler.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Admin/Handlers/ArticleIndexProfileHandler.cs @@ -71,4 +71,4 @@ public override ValueTask> GetFieldsAsync( }, ]; return ValueTask.FromResult(fields); } -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Admin/ViewModels/SettingsViewModel.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Admin/ViewModels/SettingsViewModel.cs index 8a2ffe8e..f1bfaf6b 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Admin/ViewModels/SettingsViewModel.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Admin/ViewModels/SettingsViewModel.cs @@ -1,5 +1,5 @@ -using CrestApps.Core.AI.Copilot.Models; using CrestApps.Core.AI.Claude.Models; +using CrestApps.Core.AI.Copilot.Models; using CrestApps.Core.AI.Mcp.Models; using CrestApps.Core.AI.Models; using CrestApps.Core.Mvc.Web.Areas.AIChat.Models; diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/ChatInteractions/Controllers/ChatInteractionController.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/ChatInteractions/Controllers/ChatInteractionController.cs index 888e3988..5745c3df 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/ChatInteractions/Controllers/ChatInteractionController.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/ChatInteractions/Controllers/ChatInteractionController.cs @@ -2,9 +2,9 @@ using CrestApps.Core.AI.A2A.Models; using CrestApps.Core.AI.Chat; using CrestApps.Core.AI.Chat.Services; -using CrestApps.Core.AI.Clients; using CrestApps.Core.AI.Claude.Models; using CrestApps.Core.AI.Claude.Services; +using CrestApps.Core.AI.Clients; using CrestApps.Core.AI.Copilot.Models; using CrestApps.Core.AI.Copilot.Services; using CrestApps.Core.AI.Deployments; diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/BackgroundServices/DataSourceAlignmentBackgroundService.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/BackgroundServices/DataSourceAlignmentBackgroundService.cs index 8f300fc5..99bc3660 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/BackgroundServices/DataSourceAlignmentBackgroundService.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/BackgroundServices/DataSourceAlignmentBackgroundService.cs @@ -3,7 +3,6 @@ namespace CrestApps.Core.Mvc.Web.Areas.DataSources.BackgroundServices; - /// /// Daily alignment task that ensures AI data source indexes are fully consistent. /// Upserts missing documents from data sources and removes orphaned records. diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/BackgroundServices/DataSourceSyncBackgroundService.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/BackgroundServices/DataSourceSyncBackgroundService.cs index 08fce99e..2d4c3cbb 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/BackgroundServices/DataSourceSyncBackgroundService.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/BackgroundServices/DataSourceSyncBackgroundService.cs @@ -3,7 +3,6 @@ namespace CrestApps.Core.Mvc.Web.Areas.DataSources.BackgroundServices; - /// /// Periodically synchronizes AI data source documents with their configured search indexes. /// Runs every 5 minutes to detect new, updated, or removed data source documents. diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/Services/MvcAIDataSourceIndexingQueue.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/Services/MvcAIDataSourceIndexingQueue.cs index 38baecf7..12523e80 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/Services/MvcAIDataSourceIndexingQueue.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/DataSources/Services/MvcAIDataSourceIndexingQueue.cs @@ -95,4 +95,4 @@ internal enum MvcAIDataSourceIndexingWorkItemType DeleteDataSource, SyncSourceDocuments, RemoveSourceDocuments, -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Indexing/Services/IndexProfileTypeRules.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Indexing/Services/IndexProfileTypeRules.cs index fc73228d..b487be46 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Indexing/Services/IndexProfileTypeRules.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Indexing/Services/IndexProfileTypeRules.cs @@ -14,4 +14,4 @@ public static bool SupportsEmbeddingSelection(string type) { return !string.Equals(type, IndexProfileTypes.Articles, StringComparison.OrdinalIgnoreCase); } -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Mcp/Controllers/McpConnectionController.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Mcp/Controllers/McpConnectionController.cs index 6620e86b..522369e2 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Mcp/Controllers/McpConnectionController.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Mcp/Controllers/McpConnectionController.cs @@ -472,4 +472,4 @@ private static McpConnectionViewModel ToViewModel(McpConnection connection) return model; } -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Mcp/Controllers/McpPromptController.cs b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Mcp/Controllers/McpPromptController.cs index a63ac9af..b5611a3b 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Areas/Mcp/Controllers/McpPromptController.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Areas/Mcp/Controllers/McpPromptController.cs @@ -146,4 +146,4 @@ private static void Apply(McpPromptViewModel model, McpPrompt prompt, List "?", }; } -} \ No newline at end of file +} diff --git a/src/Startup/CrestApps.Core.Mvc.Web/Tools/SendEmailTool.cs b/src/Startup/CrestApps.Core.Mvc.Web/Tools/SendEmailTool.cs index 7b318c94..db7c560b 100644 --- a/src/Startup/CrestApps.Core.Mvc.Web/Tools/SendEmailTool.cs +++ b/src/Startup/CrestApps.Core.Mvc.Web/Tools/SendEmailTool.cs @@ -65,4 +65,4 @@ private static bool TryGetRequiredString(AIFunctionArguments arguments, string k value = TryGetOptionalString(arguments, key); return !string.IsNullOrWhiteSpace(value); } -} \ No newline at end of file +} diff --git a/src/Stores/CrestApps.Core.Data.EntityCore/Services/CatalogRecordFactory.cs b/src/Stores/CrestApps.Core.Data.EntityCore/Services/CatalogRecordFactory.cs index a590dc90..a289a1c4 100644 --- a/src/Stores/CrestApps.Core.Data.EntityCore/Services/CatalogRecordFactory.cs +++ b/src/Stores/CrestApps.Core.Data.EntityCore/Services/CatalogRecordFactory.cs @@ -92,4 +92,4 @@ public static T Materialize(CatalogRecord record) ArgumentNullException.ThrowIfNull(record); return EntityCoreStoreSerializer.Deserialize(record.Payload); } -} \ No newline at end of file +} diff --git a/src/Stores/CrestApps.Core.Data.EntityCore/Services/DocumentCatalog.cs b/src/Stores/CrestApps.Core.Data.EntityCore/Services/DocumentCatalog.cs index 109b11de..13c94f96 100644 --- a/src/Stores/CrestApps.Core.Data.EntityCore/Services/DocumentCatalog.cs +++ b/src/Stores/CrestApps.Core.Data.EntityCore/Services/DocumentCatalog.cs @@ -166,4 +166,4 @@ protected virtual ValueTask SavingAsync(T record) { return ValueTask.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreAIChatSessionManager.cs b/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreAIChatSessionManager.cs index b729089f..c786a5fd 100644 --- a/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreAIChatSessionManager.cs +++ b/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreAIChatSessionManager.cs @@ -200,4 +200,4 @@ private static void UpdateRecord(AIChatSessionRecord record, AIChatSession sessi record.LastActivityUtc = session.LastActivityUtc; record.Payload = EntityCoreStoreSerializer.Serialize(session); } -} \ No newline at end of file +} diff --git a/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreSearchIndexProfileStore.cs b/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreSearchIndexProfileStore.cs index c23da541..c05431f7 100644 --- a/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreSearchIndexProfileStore.cs +++ b/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreSearchIndexProfileStore.cs @@ -16,4 +16,4 @@ public async Task> GetByTypeAsync(string var records = await GetReadQuery().Where(x => x.Type == type).ToListAsync(); return records.Select(CatalogRecordFactory.Materialize).ToArray(); } -} \ No newline at end of file +} diff --git a/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreStoreSerializer.cs b/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreStoreSerializer.cs index 79b36e62..1e1f8e77 100644 --- a/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreStoreSerializer.cs +++ b/src/Stores/CrestApps.Core.Data.EntityCore/Services/EntityCoreStoreSerializer.cs @@ -17,4 +17,4 @@ public static T Deserialize(string payload) { return JsonSerializer.Deserialize(payload, _jsonSerializerOptions); } -} \ No newline at end of file +} diff --git a/src/Utilities/CrestApps.Core.Support/Json/BidirectionalJsonStringEnumConverterFactory.cs b/src/Utilities/CrestApps.Core.Support/Json/BidirectionalJsonStringEnumConverterFactory.cs index e715a3d2..fceab13a 100644 --- a/src/Utilities/CrestApps.Core.Support/Json/BidirectionalJsonStringEnumConverterFactory.cs +++ b/src/Utilities/CrestApps.Core.Support/Json/BidirectionalJsonStringEnumConverterFactory.cs @@ -24,4 +24,4 @@ public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializer { return _converter.CreateConverter(typeToConvert, options); } -} \ No newline at end of file +} diff --git a/src/Utilities/CrestApps.Core.Support/Str.cs b/src/Utilities/CrestApps.Core.Support/Str.cs index c8a98a4d..1e0a3218 100644 --- a/src/Utilities/CrestApps.Core.Support/Str.cs +++ b/src/Utilities/CrestApps.Core.Support/Str.cs @@ -101,7 +101,6 @@ public static string AddOrdinal(int num) }; } - public static string Truncate(string value, int maxLength) { if (string.IsNullOrEmpty(value)) @@ -112,7 +111,6 @@ public static string Truncate(string value, int maxLength) return value.Length <= maxLength ? value : value.Substring(0, maxLength); } - public static string TrimEnd(string subject, string pattern) { return TrimEnd(subject, pattern, StringComparison.Ordinal); @@ -211,7 +209,6 @@ public static string TrimEnd(string subject, string pattern, StringComparison ty return subject; } - public static int CountOccurrences(string text, string pattern) { var count = 0; @@ -270,7 +267,6 @@ public static string AppendOnce(string original, string toAppend = "/") return original + toAppend; } - public static string PrependOnce(string original, string toPrefix = "/") { if (original == null || original.StartsWith(toPrefix)) @@ -337,7 +333,6 @@ public static string AfterFirstInstance(string str, string lastString) return substring; } - public static string AfterLastInstance(string str, string lastString) { if (string.IsNullOrWhiteSpace(str) || string.IsNullOrEmpty(lastString)) diff --git a/src/Utilities/CrestApps.Core.Support/StreamExtensions.cs b/src/Utilities/CrestApps.Core.Support/StreamExtensions.cs index 46771521..57bfaaee 100644 --- a/src/Utilities/CrestApps.Core.Support/StreamExtensions.cs +++ b/src/Utilities/CrestApps.Core.Support/StreamExtensions.cs @@ -9,7 +9,6 @@ public static byte[] ReadAllBytes(this Stream instream) return stream.ToArray(); } - using var memoryStream = new MemoryStream(); instream.CopyTo(memoryStream); diff --git a/src/Utilities/CrestApps.Core.Support/StringExtensions.cs b/src/Utilities/CrestApps.Core.Support/StringExtensions.cs index 372da5d9..4ce8ef39 100644 --- a/src/Utilities/CrestApps.Core.Support/StringExtensions.cs +++ b/src/Utilities/CrestApps.Core.Support/StringExtensions.cs @@ -33,4 +33,4 @@ public static string GetControllerName(this string name) { return Str.TrimEnd(name, "Controller", StringComparison.OrdinalIgnoreCase); } -} \ No newline at end of file +} diff --git a/src/Utilities/CrestApps.Core.Support/TypeExtensions.cs b/src/Utilities/CrestApps.Core.Support/TypeExtensions.cs index e19f74f9..f1293cc9 100644 --- a/src/Utilities/CrestApps.Core.Support/TypeExtensions.cs +++ b/src/Utilities/CrestApps.Core.Support/TypeExtensions.cs @@ -14,7 +14,6 @@ public static object GetSafeObject(this Type type, string value) var trueType = Nullable.GetUnderlyingType(type) ?? type; - if (trueType == typeof(string)) { return value; diff --git a/tests/CrestApps.Core.Tests/AITemplates/AIInvocationScopeTests.cs b/tests/CrestApps.Core.Tests/AITemplates/AIInvocationScopeTests.cs index f5f41584..1de0d29c 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/AIInvocationScopeTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/AIInvocationScopeTests.cs @@ -1,8 +1,7 @@ using CrestApps.Core.AI.Models; using CrestApps.Core.AI.Orchestration; -namespace CrestApps.OrchardCore.Tests.AI; - +namespace CrestApps.Core.Tests.AITemplates; /// /// Tests that provides true per-invocation isolation diff --git a/tests/CrestApps.Core.Tests/AITemplates/DataSources/DataSourceVectorSearchFilterTests.cs b/tests/CrestApps.Core.Tests/AITemplates/DataSources/DataSourceVectorSearchFilterTests.cs index d90132ab..de3a868c 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/DataSources/DataSourceVectorSearchFilterTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/DataSources/DataSourceVectorSearchFilterTests.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Text; -namespace CrestApps.OrchardCore.Tests.AI.DataSources; +namespace CrestApps.Core.Tests.AITemplates.DataSources; public sealed class DataSourceVectorSearchFilterTests { diff --git a/tests/CrestApps.Core.Tests/AITemplates/Prompting/AITemplateBuilderTests.cs b/tests/CrestApps.Core.Tests/AITemplates/Prompting/AITemplateBuilderTests.cs index db85dfd3..3f7787b4 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/Prompting/AITemplateBuilderTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/Prompting/AITemplateBuilderTests.cs @@ -2,7 +2,7 @@ using CrestApps.Core.Templates.Models; using CrestApps.Core.Templates.Services; -namespace CrestApps.OrchardCore.Tests.AI.Prompting; +namespace CrestApps.Core.Tests.AITemplates.Prompting; public sealed class AITemplateBuilderTests { @@ -191,4 +191,4 @@ public Task MergeAsync(IEnumerable ids, IDictionary(null); } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/AITemplates/Prompting/AITemplateProviderTests.cs b/tests/CrestApps.Core.Tests/AITemplates/Prompting/AITemplateProviderTests.cs index c85b0a78..9a636a33 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/Prompting/AITemplateProviderTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/Prompting/AITemplateProviderTests.cs @@ -5,7 +5,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; -namespace CrestApps.OrchardCore.Tests.AI.Prompting; +namespace CrestApps.Core.Tests.AITemplates.Prompting; public sealed class OptionsAITemplateProviderTests { @@ -253,7 +253,7 @@ public async Task GetTemplatesAsync_CustomSourceAndFeatureId() public async Task GetTemplatesAsync_FrameworkAssemblyIncludesDocumentContextHeader() { var parsers = new ITemplateParser[] { new DefaultMarkdownTemplateParser() }; - var assembly = typeof(CrestApps.Core.AI.AITemplateIds).Assembly; + var assembly = typeof(AI.AITemplateIds).Assembly; var provider = new EmbeddedResourceTemplateProvider(assembly, parsers); var templates = await provider.GetTemplatesAsync(); @@ -267,7 +267,7 @@ public async Task GetTemplatesAsync_FrameworkAssemblyIncludesDocumentContextHead public async Task GetTemplatesAsync_FrameworkAssemblyIncludesExtractedDataAvailability() { var parsers = new ITemplateParser[] { new DefaultMarkdownTemplateParser() }; - var assembly = typeof(CrestApps.Core.AI.AITemplateIds).Assembly; + var assembly = typeof(AI.AITemplateIds).Assembly; var provider = new EmbeddedResourceTemplateProvider(assembly, parsers); var templates = await provider.GetTemplatesAsync(); diff --git a/tests/CrestApps.Core.Tests/AITemplates/Prompting/DefaultAITemplateServiceTests.cs b/tests/CrestApps.Core.Tests/AITemplates/Prompting/DefaultAITemplateServiceTests.cs index 590605e3..b5c467e6 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/Prompting/DefaultAITemplateServiceTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/Prompting/DefaultAITemplateServiceTests.cs @@ -5,7 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; -namespace CrestApps.OrchardCore.Tests.AI.Prompting; +namespace CrestApps.Core.Tests.AITemplates.Prompting; public sealed class DefaultAITemplateServiceTests { diff --git a/tests/CrestApps.Core.Tests/AITemplates/Prompting/DefaultMarkdownAITemplateParserTests.cs b/tests/CrestApps.Core.Tests/AITemplates/Prompting/DefaultMarkdownAITemplateParserTests.cs index 89de029e..a47f07b2 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/Prompting/DefaultMarkdownAITemplateParserTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/Prompting/DefaultMarkdownAITemplateParserTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.Templates.Parsing; -namespace CrestApps.OrchardCore.Tests.AI.Prompting; +namespace CrestApps.Core.Tests.AITemplates.Prompting; public sealed class DefaultMarkdownAITemplateParserTests { diff --git a/tests/CrestApps.Core.Tests/AITemplates/Prompting/FluidAITemplateEngineTests.cs b/tests/CrestApps.Core.Tests/AITemplates/Prompting/FluidAITemplateEngineTests.cs index 5cb28f7b..3ef71ff6 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/Prompting/FluidAITemplateEngineTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/Prompting/FluidAITemplateEngineTests.cs @@ -2,7 +2,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; -namespace CrestApps.OrchardCore.Tests.AI.Prompting; +namespace CrestApps.Core.Tests.AITemplates.Prompting; public sealed class FluidAITemplateEngineTests { diff --git a/tests/CrestApps.Core.Tests/AITemplates/Prompting/RenderAITemplateTagTests.cs b/tests/CrestApps.Core.Tests/AITemplates/Prompting/RenderAITemplateTagTests.cs index 403ca608..0a16388d 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/Prompting/RenderAITemplateTagTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/Prompting/RenderAITemplateTagTests.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; -namespace CrestApps.OrchardCore.Tests.AI.Prompting; +namespace CrestApps.Core.Tests.AITemplates.Prompting; public sealed class RenderAITemplateTagTests { @@ -141,4 +141,4 @@ public TestTool(string name, string description, string source) public string Description { get; } public string Source { get; } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/AITemplates/Prompting/TemplateLiquidRenderingTests.cs b/tests/CrestApps.Core.Tests/AITemplates/Prompting/TemplateLiquidRenderingTests.cs index 5196f85e..65681c06 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/Prompting/TemplateLiquidRenderingTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/Prompting/TemplateLiquidRenderingTests.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; -namespace CrestApps.OrchardCore.Tests.AI.Prompting; +namespace CrestApps.Core.Tests.AITemplates.Prompting; /// /// Verifies that Liquid templates can access typed .NET object properties diff --git a/tests/CrestApps.Core.Tests/AITemplates/RagTextNormalizerTests.cs b/tests/CrestApps.Core.Tests/AITemplates/RagTextNormalizerTests.cs index 1d147475..1a6c6591 100644 --- a/tests/CrestApps.Core.Tests/AITemplates/RagTextNormalizerTests.cs +++ b/tests/CrestApps.Core.Tests/AITemplates/RagTextNormalizerTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI.Services; -namespace CrestApps.OrchardCore.Tests.AI; +namespace CrestApps.Core.Tests.AITemplates; public sealed class RagTextNormalizerTests { @@ -51,7 +51,6 @@ public async Task NormalizeContentAsync_ConvertsBlockElementsToNewlines() Assert.Contains("Paragraph two.", result); } - [Fact] public async Task NormalizeContentAsync_StripsMarkdownFormatting() { diff --git a/tests/CrestApps.Core.Tests/Abstractions/Models/AIDeploymentTests.cs b/tests/CrestApps.Core.Tests/Abstractions/Models/AIDeploymentTests.cs index 8a635cf2..1db1b423 100644 --- a/tests/CrestApps.Core.Tests/Abstractions/Models/AIDeploymentTests.cs +++ b/tests/CrestApps.Core.Tests/Abstractions/Models/AIDeploymentTests.cs @@ -1,7 +1,7 @@ using System.Text.Json; using CrestApps.Core.AI.Models; -namespace CrestApps.OrchardCore.Tests.Abstractions.Models; +namespace CrestApps.Core.Tests.Abstractions.Models; public sealed class AIDeploymentTests { diff --git a/tests/CrestApps.Core.Tests/ChatNotifications/CancelTransferNotificationActionHandlerTests.cs b/tests/CrestApps.Core.Tests/ChatNotifications/CancelTransferNotificationActionHandlerTests.cs index 5efd3d7d..8b96f4c3 100644 --- a/tests/CrestApps.Core.Tests/ChatNotifications/CancelTransferNotificationActionHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/ChatNotifications/CancelTransferNotificationActionHandlerTests.cs @@ -7,7 +7,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.ChatNotifications; +namespace CrestApps.Core.Tests.ChatNotifications; public sealed class CancelTransferNotificationActionHandlerTests { diff --git a/tests/CrestApps.Core.Tests/ChatNotifications/DefaultChatNotificationSenderTests.cs b/tests/CrestApps.Core.Tests/ChatNotifications/DefaultChatNotificationSenderTests.cs index bf759d43..b0804dd2 100644 --- a/tests/CrestApps.Core.Tests/ChatNotifications/DefaultChatNotificationSenderTests.cs +++ b/tests/CrestApps.Core.Tests/ChatNotifications/DefaultChatNotificationSenderTests.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Moq; -namespace CrestApps.OrchardCore.Tests.ChatNotifications; +namespace CrestApps.Core.Tests.ChatNotifications; public sealed class DefaultChatNotificationSenderTests { diff --git a/tests/CrestApps.Core.Tests/ChatNotifications/EndSessionNotificationActionHandlerTests.cs b/tests/CrestApps.Core.Tests/ChatNotifications/EndSessionNotificationActionHandlerTests.cs index a087e49e..f2b97f68 100644 --- a/tests/CrestApps.Core.Tests/ChatNotifications/EndSessionNotificationActionHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/ChatNotifications/EndSessionNotificationActionHandlerTests.cs @@ -7,7 +7,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.ChatNotifications; +namespace CrestApps.Core.Tests.ChatNotifications; public sealed class EndSessionNotificationActionHandlerTests { @@ -142,4 +142,4 @@ public IEnumerable GetAllStrings(bool includeParentCultures) return []; } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/ChatNotifications/ExternalChatRelayConnectionManagerTests.cs b/tests/CrestApps.Core.Tests/ChatNotifications/ExternalChatRelayConnectionManagerTests.cs index a6d6566b..dab7b373 100644 --- a/tests/CrestApps.Core.Tests/ChatNotifications/ExternalChatRelayConnectionManagerTests.cs +++ b/tests/CrestApps.Core.Tests/ChatNotifications/ExternalChatRelayConnectionManagerTests.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.ChatNotifications; +namespace CrestApps.Core.Tests.ChatNotifications; public sealed class ExternalChatRelayConnectionManagerTests { diff --git a/tests/CrestApps.Core.Tests/Core/AIProfileCompletionContextBuilderHandlerTests.cs b/tests/CrestApps.Core.Tests/Core/AIProfileCompletionContextBuilderHandlerTests.cs index ba52726b..f91f7fe0 100644 --- a/tests/CrestApps.Core.Tests/Core/AIProfileCompletionContextBuilderHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/AIProfileCompletionContextBuilderHandlerTests.cs @@ -4,7 +4,7 @@ using CrestApps.Core.Templates.Services; using Moq; -namespace CrestApps.OrchardCore.Tests.Core; +namespace CrestApps.Core.Tests.Core; public sealed class AIProfileCompletionContextBuilderHandlerTests { diff --git a/tests/CrestApps.Core.Tests/Core/Chat/DataSourceChatInteractionSettingsHandlerTests.cs b/tests/CrestApps.Core.Tests/Core/Chat/DataSourceChatInteractionSettingsHandlerTests.cs index 067c1349..3243694c 100644 --- a/tests/CrestApps.Core.Tests/Core/Chat/DataSourceChatInteractionSettingsHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Chat/DataSourceChatInteractionSettingsHandlerTests.cs @@ -7,7 +7,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.Core.Chat; +namespace CrestApps.Core.Tests.Core.Chat; public sealed class DataSourceChatInteractionSettingsHandlerTests { diff --git a/tests/CrestApps.Core.Tests/Core/Chat/DocumentPreemptiveRagHandlerTests.cs b/tests/CrestApps.Core.Tests/Core/Chat/DocumentPreemptiveRagHandlerTests.cs index ea3e3572..0b17515b 100644 --- a/tests/CrestApps.Core.Tests/Core/Chat/DocumentPreemptiveRagHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Chat/DocumentPreemptiveRagHandlerTests.cs @@ -15,7 +15,7 @@ using Moq; #pragma warning disable MEAI001 -namespace CrestApps.OrchardCore.Tests.Core.Chat; +namespace CrestApps.Core.Tests.Core.Chat; public sealed class DocumentPreemptiveRagHandlerTests { diff --git a/tests/CrestApps.Core.Tests/Core/Chat/ExtractedDataOrchestrationHandlerTests.cs b/tests/CrestApps.Core.Tests/Core/Chat/ExtractedDataOrchestrationHandlerTests.cs index 5cc31c38..cec2cf1d 100644 --- a/tests/CrestApps.Core.Tests/Core/Chat/ExtractedDataOrchestrationHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Chat/ExtractedDataOrchestrationHandlerTests.cs @@ -5,7 +5,7 @@ using CrestApps.Core.Templates.Services; using Microsoft.Extensions.Logging.Abstractions; -namespace CrestApps.OrchardCore.Tests.Core.Chat; +namespace CrestApps.Core.Tests.Core.Chat; public sealed class ExtractedDataOrchestrationHandlerTests { @@ -118,4 +118,4 @@ private static IEnumerable GetValues(object value) return value.GetType().GetProperty("Values")?.GetValue(value) as IEnumerable ?? []; } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Core/ChatResponseHandlerContextTests.cs b/tests/CrestApps.Core.Tests/Core/ChatResponseHandlerContextTests.cs index 5ed7d19e..741c7516 100644 --- a/tests/CrestApps.Core.Tests/Core/ChatResponseHandlerContextTests.cs +++ b/tests/CrestApps.Core.Tests/Core/ChatResponseHandlerContextTests.cs @@ -2,7 +2,7 @@ using CrestApps.Core.AI.ResponseHandling; using Microsoft.Extensions.DependencyInjection; -namespace CrestApps.OrchardCore.Tests.Core; +namespace CrestApps.Core.Tests.Core; public sealed class ChatResponseHandlerContextTests { diff --git a/tests/CrestApps.Core.Tests/Core/Mcp/CosineSimilarityTests.cs b/tests/CrestApps.Core.Tests/Core/Mcp/CosineSimilarityTests.cs index 5c99c093..9083447c 100644 --- a/tests/CrestApps.Core.Tests/Core/Mcp/CosineSimilarityTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Mcp/CosineSimilarityTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI.Mcp.Services; -namespace CrestApps.OrchardCore.Tests.Core.Mcp; +namespace CrestApps.Core.Tests.Core.Mcp; public sealed class CosineSimilarityTests { diff --git a/tests/CrestApps.Core.Tests/Core/Mcp/DefaultMcpMetadataPromptGeneratorTests.cs b/tests/CrestApps.Core.Tests/Core/Mcp/DefaultMcpMetadataPromptGeneratorTests.cs index 3db82221..265f798f 100644 --- a/tests/CrestApps.Core.Tests/Core/Mcp/DefaultMcpMetadataPromptGeneratorTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Mcp/DefaultMcpMetadataPromptGeneratorTests.cs @@ -1,7 +1,7 @@ using CrestApps.Core.AI.Mcp.Models; using CrestApps.Core.AI.Mcp.Services; -namespace CrestApps.OrchardCore.Tests.Core.Mcp; +namespace CrestApps.Core.Tests.Core.Mcp; public sealed class DefaultMcpMetadataPromptGeneratorTests { diff --git a/tests/CrestApps.Core.Tests/Core/Mcp/InMemoryMcpCapabilityEmbeddingCacheTests.cs b/tests/CrestApps.Core.Tests/Core/Mcp/InMemoryMcpCapabilityEmbeddingCacheTests.cs index 4942b1f4..7678fb57 100644 --- a/tests/CrestApps.Core.Tests/Core/Mcp/InMemoryMcpCapabilityEmbeddingCacheTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Mcp/InMemoryMcpCapabilityEmbeddingCacheTests.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.AI; using Microsoft.Extensions.Logging.Abstractions; -namespace CrestApps.OrchardCore.Tests.Core.Mcp; +namespace CrestApps.Core.Tests.Core.Mcp; public sealed class InMemoryMcpCapabilityEmbeddingCacheTests { diff --git a/tests/CrestApps.Core.Tests/Core/Mcp/McpResourceTypeHandlerBaseTests.cs b/tests/CrestApps.Core.Tests/Core/Mcp/McpResourceTypeHandlerBaseTests.cs index 026e2898..867ab41b 100644 --- a/tests/CrestApps.Core.Tests/Core/Mcp/McpResourceTypeHandlerBaseTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Mcp/McpResourceTypeHandlerBaseTests.cs @@ -2,7 +2,7 @@ using CrestApps.Core.AI.Mcp.Models; using ModelContextProtocol.Protocol; -namespace CrestApps.OrchardCore.Tests.Core.Mcp; +namespace CrestApps.Core.Tests.Core.Mcp; public sealed class McpResourceTypeHandlerBaseTests { diff --git a/tests/CrestApps.Core.Tests/Core/Mcp/McpResourceUriTests.cs b/tests/CrestApps.Core.Tests/Core/Mcp/McpResourceUriTests.cs index 7ca29649..5c91f4eb 100644 --- a/tests/CrestApps.Core.Tests/Core/Mcp/McpResourceUriTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Mcp/McpResourceUriTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI.Mcp; -namespace CrestApps.OrchardCore.Tests.Core.Mcp; +namespace CrestApps.Core.Tests.Core.Mcp; public sealed class McpResourceUriTests { diff --git a/tests/CrestApps.Core.Tests/Core/Mcp/ServiceCollectionExtensionsTests.cs b/tests/CrestApps.Core.Tests/Core/Mcp/ServiceCollectionExtensionsTests.cs index e936f33a..ffc2cef4 100644 --- a/tests/CrestApps.Core.Tests/Core/Mcp/ServiceCollectionExtensionsTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Mcp/ServiceCollectionExtensionsTests.cs @@ -6,7 +6,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -namespace CrestApps.OrchardCore.Tests.Core.Mcp; +namespace CrestApps.Core.Tests.Core.Mcp; public sealed class ServiceCollectionExtensionsTests { diff --git a/tests/CrestApps.Core.Tests/Core/Mcp/TokenizeTests.cs b/tests/CrestApps.Core.Tests/Core/Mcp/TokenizeTests.cs index 2e3fd499..693732d7 100644 --- a/tests/CrestApps.Core.Tests/Core/Mcp/TokenizeTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Mcp/TokenizeTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI; -namespace CrestApps.OrchardCore.Tests.Core.Mcp; +namespace CrestApps.Core.Tests.Core.Mcp; public sealed class TokenizeTests { diff --git a/tests/CrestApps.Core.Tests/Core/Models/DefaultAIOptionsTests.cs b/tests/CrestApps.Core.Tests/Core/Models/DefaultAIOptionsTests.cs index c9257c0d..0651bcc0 100644 --- a/tests/CrestApps.Core.Tests/Core/Models/DefaultAIOptionsTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Models/DefaultAIOptionsTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI.Models; -namespace CrestApps.OrchardCore.Tests.Core.Models; +namespace CrestApps.Core.Tests.Core.Models; public sealed class DefaultAIOptionsTests { diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/DataSourceOrchestrationHandlerTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/DataSourceOrchestrationHandlerTests.cs index 45916d17..3e9a076d 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/DataSourceOrchestrationHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/DataSourceOrchestrationHandlerTests.cs @@ -7,7 +7,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class DataSourceOrchestrationHandlerTests { @@ -77,4 +77,4 @@ public Task MergeAsync(IEnumerable ids, IDictionary $"[Template: {id}]"))); } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestrationContextBuilderTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestrationContextBuilderTests.cs index 132520d7..772d1b72 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestrationContextBuilderTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestrationContextBuilderTests.cs @@ -3,7 +3,7 @@ using CrestApps.Core.AI.Services; using Microsoft.Extensions.Logging.Abstractions; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class DefaultOrchestrationContextBuilderTests { diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestratorResolverTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestratorResolverTests.cs index d6b13f06..03e8319c 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestratorResolverTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestratorResolverTests.cs @@ -13,7 +13,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class DefaultOrchestratorResolverTests { @@ -136,4 +136,4 @@ public Task MergeAsync(IEnumerable ids, IDictionary(null); } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestratorTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestratorTests.cs index 604ab508..864fbd1d 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestratorTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultOrchestratorTests.cs @@ -14,7 +14,7 @@ #pragma warning disable MEAI001 // Text-to-speech APIs from Microsoft.Extensions.AI are preview and require explicit opt-in at each usage site. -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class DefaultOrchestratorTests { diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultToolRegistryTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultToolRegistryTests.cs index d3730ee8..973b6c1d 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultToolRegistryTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/DefaultToolRegistryTests.cs @@ -2,10 +2,9 @@ using CrestApps.Core.AI.Models; using CrestApps.Core.AI.Orchestration; using CrestApps.Core.AI.Tooling; - using Microsoft.Extensions.Logging.Abstractions; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class DefaultToolRegistryTests { diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/DocumentOrchestrationHandlerTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/DocumentOrchestrationHandlerTests.cs index 6ba8d71c..057b70ff 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/DocumentOrchestrationHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/DocumentOrchestrationHandlerTests.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class DocumentOrchestrationHandlerTests { @@ -303,4 +303,4 @@ public Task MergeAsync(IEnumerable ids, IDictionary $"[Template: {id}]"))); } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/LuceneTextTokenizerTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/LuceneTextTokenizerTests.cs index d8348994..df92309e 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/LuceneTextTokenizerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/LuceneTextTokenizerTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class LuceneTextTokenizerTests { diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/OrchestrationContextTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/OrchestrationContextTests.cs index b2716041..b61a8848 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/OrchestrationContextTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/OrchestrationContextTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI.Models; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class OrchestrationContextTests { diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/PreemptiveRagOrchestrationHandlerTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/PreemptiveRagOrchestrationHandlerTests.cs index b651ef30..0ac64625 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/PreemptiveRagOrchestrationHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/PreemptiveRagOrchestrationHandlerTests.cs @@ -11,7 +11,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class PreemptiveRagOrchestrationHandlerTests { @@ -244,4 +244,4 @@ public Task MergeAsync(IEnumerable ids, IDictionary $"[Template: {id}]"))); } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/SystemToolRegistryProviderTests.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/SystemToolRegistryProviderTests.cs index f56d5ed0..f6d4d2a5 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/SystemToolRegistryProviderTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/SystemToolRegistryProviderTests.cs @@ -6,7 +6,7 @@ using Microsoft.Extensions.Options; -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; public sealed class SystemToolRegistryProviderTests { diff --git a/tests/CrestApps.Core.Tests/Core/Orchestration/TestHelpers.cs b/tests/CrestApps.Core.Tests/Core/Orchestration/TestHelpers.cs index 32488f46..1371aa3b 100644 --- a/tests/CrestApps.Core.Tests/Core/Orchestration/TestHelpers.cs +++ b/tests/CrestApps.Core.Tests/Core/Orchestration/TestHelpers.cs @@ -7,7 +7,7 @@ #pragma warning disable MEAI001 // Text-to-speech APIs from Microsoft.Extensions.AI are preview and require explicit opt-in at each usage site. -namespace CrestApps.OrchardCore.Tests.Core.Orchestration; +namespace CrestApps.Core.Tests.Core.Orchestration; /// /// A test orchestrator used for verifying orchestrator resolution. /// diff --git a/tests/CrestApps.Core.Tests/Core/Services/AIMemoryIndexingServiceTests.cs b/tests/CrestApps.Core.Tests/Core/Services/AIMemoryIndexingServiceTests.cs index 2c36fc0e..ad75f713 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/AIMemoryIndexingServiceTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/AIMemoryIndexingServiceTests.cs @@ -11,7 +11,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Core.Services; +namespace CrestApps.Core.Tests.Core.Services; public sealed class AIMemoryIndexingServiceTests { diff --git a/tests/CrestApps.Core.Tests/Core/Services/AIMemorySearchServiceTests.cs b/tests/CrestApps.Core.Tests/Core/Services/AIMemorySearchServiceTests.cs index 9cdb92fa..d28d1e63 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/AIMemorySearchServiceTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/AIMemorySearchServiceTests.cs @@ -11,7 +11,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Core.Services; +namespace CrestApps.Core.Tests.Core.Services; public sealed class AIMemorySearchServiceTests { diff --git a/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestCatalogEntry.cs b/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestCatalogEntry.cs index ac3b55c9..0f11cc9f 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestCatalogEntry.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestCatalogEntry.cs @@ -1,6 +1,6 @@ using CrestApps.Core.Models; -namespace CrestApps.OrchardCore.Tests.Core.Services.Catalogs.Services; +namespace CrestApps.Core.Tests.Core.Services.Catalogs.Services; public sealed class TestCatalogEntry : CatalogItem { diff --git a/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestCatalogEntryHandler.cs b/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestCatalogEntryHandler.cs index a2fa0650..76cf528c 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestCatalogEntryHandler.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestCatalogEntryHandler.cs @@ -1,7 +1,7 @@ using CrestApps.Core.Models; using CrestApps.Core.Services; -namespace CrestApps.OrchardCore.Tests.Core.Services.Catalogs.Services; +namespace CrestApps.Core.Tests.Core.Services.Catalogs.Services; internal sealed class TestCatalogEntryHandler : ICatalogEntryHandler { diff --git a/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestNamedCatalogEntry.cs b/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestNamedCatalogEntry.cs index 1f758c47..32bc3547 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestNamedCatalogEntry.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestNamedCatalogEntry.cs @@ -1,7 +1,7 @@ using CrestApps.Core; using CrestApps.Core.Models; -namespace CrestApps.OrchardCore.Tests.Core.Services.Catalogs.Services; +namespace CrestApps.Core.Tests.Core.Services.Catalogs.Services; public sealed class TestNamedCatalogEntry : CatalogItem, INameAwareModel { diff --git a/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestNamedSourceCatalogEntry.cs b/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestNamedSourceCatalogEntry.cs index d88ab67a..621618b0 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestNamedSourceCatalogEntry.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/Catalogs/Services/TestNamedSourceCatalogEntry.cs @@ -1,7 +1,7 @@ using CrestApps.Core; using CrestApps.Core.Models; -namespace CrestApps.OrchardCore.Tests.Core.Services.Catalogs.Services; +namespace CrestApps.Core.Tests.Core.Services.Catalogs.Services; public sealed class TestNamedSourceCatalogEntry : CatalogItem, INameAwareModel, ISourceAwareModel { diff --git a/tests/CrestApps.Core.Tests/Core/Services/DefaultAIProfileTemplateManagerTests.cs b/tests/CrestApps.Core.Tests/Core/Services/DefaultAIProfileTemplateManagerTests.cs index 42f618ff..0251de95 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/DefaultAIProfileTemplateManagerTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/DefaultAIProfileTemplateManagerTests.cs @@ -6,7 +6,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.Core.Services; +namespace CrestApps.Core.Tests.Core.Services; public sealed class DefaultAIProfileTemplateManagerTests { diff --git a/tests/CrestApps.Core.Tests/Core/Services/EmbeddedResourceAIProfileTemplateProviderTests.cs b/tests/CrestApps.Core.Tests/Core/Services/EmbeddedResourceAIProfileTemplateProviderTests.cs index 7da2c480..ce21ba09 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/EmbeddedResourceAIProfileTemplateProviderTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/EmbeddedResourceAIProfileTemplateProviderTests.cs @@ -4,7 +4,7 @@ using CrestApps.Core.AI.Services; using CrestApps.Core.Templates.Parsing; -namespace CrestApps.OrchardCore.Tests.Core.Services; +namespace CrestApps.Core.Tests.Core.Services; public sealed class EmbeddedResourceAIProfileTemplateProviderTests { @@ -12,7 +12,7 @@ public sealed class EmbeddedResourceAIProfileTemplateProviderTests public async Task GetTemplatesAsync_DiscoversAllEmbeddedProfileTemplates() { var provider = new EmbeddedResourceAIProfileTemplateProvider( - typeof(CrestApps.Core.AI.ServiceCollectionExtensions).Assembly, + typeof(AI.ServiceCollectionExtensions).Assembly, [new DefaultMarkdownTemplateParser()]); var templates = await provider.GetTemplatesAsync(); @@ -26,7 +26,7 @@ public async Task GetTemplatesAsync_DiscoversAllEmbeddedProfileTemplates() public async Task GetTemplatesAsync_MapsFrontMatterToProfileMetadata() { var provider = new EmbeddedResourceAIProfileTemplateProvider( - typeof(CrestApps.Core.AI.ServiceCollectionExtensions).Assembly, + typeof(AI.ServiceCollectionExtensions).Assembly, [new DefaultMarkdownTemplateParser()]); var templates = await provider.GetTemplatesAsync(); diff --git a/tests/CrestApps.Core.Tests/Core/Services/ODataFilterValidatorTests.cs b/tests/CrestApps.Core.Tests/Core/Services/ODataFilterValidatorTests.cs index 8db12738..95a51a26 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/ODataFilterValidatorTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/ODataFilterValidatorTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.Services; -namespace CrestApps.OrchardCore.Tests.Core.Services; +namespace CrestApps.Core.Tests.Core.Services; public sealed class ODataFilterValidatorTests { diff --git a/tests/CrestApps.Core.Tests/Core/Services/PostSession/PostSessionProcessingServiceTests.cs b/tests/CrestApps.Core.Tests/Core/Services/PostSession/PostSessionProcessingServiceTests.cs index f4f3cb1b..49ed34ca 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/PostSession/PostSessionProcessingServiceTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/PostSession/PostSessionProcessingServiceTests.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.Core.Services.PostSession; +namespace CrestApps.Core.Tests.Core.Services.PostSession; public sealed class PostSessionProcessingServiceTests { @@ -677,4 +677,4 @@ public async Task ProcessAsync_WithTools_WhenResponseIsEmpty_ShouldReturnFailedR Assert.NotNull(result["summary"].ErrorMessage); } #endregion -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Core/Services/SentenceBoundaryDetectorTests.cs b/tests/CrestApps.Core.Tests/Core/Services/SentenceBoundaryDetectorTests.cs index c367545a..c704f684 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/SentenceBoundaryDetectorTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/SentenceBoundaryDetectorTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI.Services; -namespace CrestApps.OrchardCore.Tests.Core.Services; +namespace CrestApps.Core.Tests.Core.Services; public sealed class SentenceBoundaryDetectorTests { diff --git a/tests/CrestApps.Core.Tests/Core/Services/SpeechLanguageHelperTests.cs b/tests/CrestApps.Core.Tests/Core/Services/SpeechLanguageHelperTests.cs index 3f418419..209ac463 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/SpeechLanguageHelperTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/SpeechLanguageHelperTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI.Services; -namespace CrestApps.OrchardCore.Tests.Core.Services; +namespace CrestApps.Core.Tests.Core.Services; public sealed class SpeechLanguageHelperTests { diff --git a/tests/CrestApps.Core.Tests/Core/Services/SpeechVoiceLocalizationHelperTests.cs b/tests/CrestApps.Core.Tests/Core/Services/SpeechVoiceLocalizationHelperTests.cs index 920ac4e8..d0d7aff2 100644 --- a/tests/CrestApps.Core.Tests/Core/Services/SpeechVoiceLocalizationHelperTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Services/SpeechVoiceLocalizationHelperTests.cs @@ -1,7 +1,7 @@ using System.Globalization; using CrestApps.Core.AI.Services; -namespace CrestApps.OrchardCore.Tests.Core.Services; +namespace CrestApps.Core.Tests.Core.Services; public sealed class SpeechVoiceLocalizationHelperTests { diff --git a/tests/CrestApps.Core.Tests/Core/Tools/SaveUserMemoryToolTests.cs b/tests/CrestApps.Core.Tests/Core/Tools/SaveUserMemoryToolTests.cs index dd314606..b7b1502f 100644 --- a/tests/CrestApps.Core.Tests/Core/Tools/SaveUserMemoryToolTests.cs +++ b/tests/CrestApps.Core.Tests/Core/Tools/SaveUserMemoryToolTests.cs @@ -12,7 +12,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.Core.Tools; +namespace CrestApps.Core.Tests.Core.Tools; public sealed class SaveUserMemoryToolTests { diff --git a/tests/CrestApps.Core.Tests/Extensions/AIFunctionArgumentsExtensionsTests.cs b/tests/CrestApps.Core.Tests/Extensions/AIFunctionArgumentsExtensionsTests.cs index fb97e94f..2eef7ce4 100644 --- a/tests/CrestApps.Core.Tests/Extensions/AIFunctionArgumentsExtensionsTests.cs +++ b/tests/CrestApps.Core.Tests/Extensions/AIFunctionArgumentsExtensionsTests.cs @@ -2,7 +2,7 @@ using CrestApps.Core.AI.Extensions; using Microsoft.Extensions.AI; -namespace CrestApps.OrchardCore.Tests.Extensions; +namespace CrestApps.Core.Tests.Extensions; public sealed class AIFunctionArgumentsExtensionsTests { @@ -71,7 +71,6 @@ public static void TryGetFirstString_WhenStringJsonElement_ReturnsTrueAndTheCorr Assert.Equal("Mike", value); } - [Fact] public static void TryGetFirst_WhenNumberJsonElement_ReturnsTrueAndTheCorrectValue() { diff --git a/tests/CrestApps.Core.Tests/Framework/AI/DataExtractionServiceTests.cs b/tests/CrestApps.Core.Tests/Framework/AI/DataExtractionServiceTests.cs index 5511e974..f3a75e7a 100644 --- a/tests/CrestApps.Core.Tests/Framework/AI/DataExtractionServiceTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/AI/DataExtractionServiceTests.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.AI; +namespace CrestApps.Core.Tests.Framework.AI; public sealed class DataExtractionServiceTests { @@ -127,4 +127,4 @@ private static AIChatSessionPrompt[] CreatePrompts(params string[] userMessages) { return userMessages.Select(message => new AIChatSessionPrompt { Role = ChatRole.User, Content = message, }).ToArray(); } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcAITemplateViewModelClaudeTests.cs b/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcAITemplateViewModelClaudeTests.cs index 3a88f9f3..900bef39 100644 --- a/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcAITemplateViewModelClaudeTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcAITemplateViewModelClaudeTests.cs @@ -5,7 +5,7 @@ using CrestApps.Core.AI.Models; using CrestApps.Core.Mvc.Web.Areas.AI.ViewModels; -namespace CrestApps.OrchardCore.Tests.Framework.Chat.Claude; +namespace CrestApps.Core.Tests.Framework.Chat.Claude; public sealed class MvcAITemplateViewModelClaudeTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcClaudeOptionsConfigurationTests.cs b/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcClaudeOptionsConfigurationTests.cs index 9fadf8e8..0b4ecbff 100644 --- a/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcClaudeOptionsConfigurationTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcClaudeOptionsConfigurationTests.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -namespace CrestApps.OrchardCore.Tests.Framework.Chat.Claude; +namespace CrestApps.Core.Tests.Framework.Chat.Claude; public sealed class MvcClaudeOptionsConfigurationTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcClaudeSettingsExtensionsTests.cs b/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcClaudeSettingsExtensionsTests.cs index 9c608bf1..6dc7932b 100644 --- a/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcClaudeSettingsExtensionsTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Chat.Claude/MvcClaudeSettingsExtensionsTests.cs @@ -2,7 +2,7 @@ using CrestApps.Core.Mvc.Web.Areas.AIChat.Models; using CrestApps.Core.Mvc.Web.Areas.AIChat.Services; -namespace CrestApps.OrchardCore.Tests.Framework.Chat.Claude; +namespace CrestApps.Core.Tests.Framework.Chat.Claude; public sealed class MvcClaudeSettingsExtensionsTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Chat.Copilot/MvcAITemplateViewModelCopilotTests.cs b/tests/CrestApps.Core.Tests/Framework/Chat.Copilot/MvcAITemplateViewModelCopilotTests.cs index a682eaf6..0b61e5a0 100644 --- a/tests/CrestApps.Core.Tests/Framework/Chat.Copilot/MvcAITemplateViewModelCopilotTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Chat.Copilot/MvcAITemplateViewModelCopilotTests.cs @@ -1,11 +1,11 @@ -using CrestApps.Core; using CrestApps.Core.AI; using CrestApps.Core.AI.Copilot.Models; using CrestApps.Core.AI.Copilot.Services; using CrestApps.Core.AI.Models; using CrestApps.Core.Mvc.Web.Areas.AI.ViewModels; +using CrestApps.Core.Mvc.Web.Models; -namespace CrestApps.OrchardCore.Tests.Framework.Chat.Copilot; +namespace CrestApps.Core.Tests.Framework.Chat.Copilot; public sealed class MvcAITemplateViewModelCopilotTests { @@ -79,7 +79,7 @@ public void FromTemplate_WhenLegacyMvcMemorySettingsExist_ShouldFallbackToLegacy { Source = AITemplateSources.Profile, }; - template.Put(new CrestApps.Core.Mvc.Web.Models.MemorySettings + template.Put(new MemorySettings { EnableUserMemory = true, }); diff --git a/tests/CrestApps.Core.Tests/Framework/Chat.Copilot/MvcCopilotSettingsExtensionsTests.cs b/tests/CrestApps.Core.Tests/Framework/Chat.Copilot/MvcCopilotSettingsExtensionsTests.cs index 46d5e2a2..2924148b 100644 --- a/tests/CrestApps.Core.Tests/Framework/Chat.Copilot/MvcCopilotSettingsExtensionsTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Chat.Copilot/MvcCopilotSettingsExtensionsTests.cs @@ -2,7 +2,7 @@ using CrestApps.Core.Mvc.Web.Areas.AIChat.Models; using CrestApps.Core.Mvc.Web.Areas.AIChat.Services; -namespace CrestApps.OrchardCore.Tests.Framework.Chat.Copilot; +namespace CrestApps.Core.Tests.Framework.Chat.Copilot; public sealed class MvcCopilotSettingsExtensionsTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/AIProfileViewModelClaudeTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/AIProfileViewModelClaudeTests.cs index dc0e6abc..06b9ee0b 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/AIProfileViewModelClaudeTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/AIProfileViewModelClaudeTests.cs @@ -4,7 +4,7 @@ using CrestApps.Core.AI.Models; using CrestApps.Core.Mvc.Web.Areas.AI.ViewModels; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class AIProfileViewModelClaudeTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/AIProfileViewModelTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/AIProfileViewModelTests.cs index fb946bbb..2b8e54c0 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/AIProfileViewModelTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/AIProfileViewModelTests.cs @@ -8,7 +8,7 @@ using CrestApps.Core.AI.Models; using CrestApps.Core.Mvc.Web.Areas.AI.ViewModels; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class AIProfileViewModelTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/AIProviderConnectionOptionsTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/AIProviderConnectionOptionsTests.cs index e889c079..6cc9d1fb 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/AIProviderConnectionOptionsTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/AIProviderConnectionOptionsTests.cs @@ -14,7 +14,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class AIProviderConnectionOptionsTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/ChatExtractedDataControllerTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/ChatExtractedDataControllerTests.cs index e5c8c800..6671c395 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/ChatExtractedDataControllerTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/ChatExtractedDataControllerTests.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Mvc; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class ChatExtractedDataControllerTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/ChatInteractionHubTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/ChatInteractionHubTests.cs index fdb40699..3b09d9d4 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/ChatInteractionHubTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/ChatInteractionHubTests.cs @@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class ChatInteractionHubTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/ConfigurationAIDeploymentCatalogTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/ConfigurationAIDeploymentCatalogTests.cs index fd4e4cac..6c177151 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/ConfigurationAIDeploymentCatalogTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/ConfigurationAIDeploymentCatalogTests.cs @@ -6,7 +6,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class ConfigurationAIDeploymentCatalogTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/IndexProfileTypeRulesTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/IndexProfileTypeRulesTests.cs index e38b8973..a2216648 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/IndexProfileTypeRulesTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/IndexProfileTypeRulesTests.cs @@ -14,7 +14,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class IndexProfileTypeRulesTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/MvcAIChatDocumentEventHandlerTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/MvcAIChatDocumentEventHandlerTests.cs index 90cfe599..c4704584 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/MvcAIChatDocumentEventHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/MvcAIChatDocumentEventHandlerTests.cs @@ -3,7 +3,7 @@ using CrestApps.Core.Mvc.Web.Areas.AIChat.Services; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class MvcAIChatDocumentEventHandlerTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/MvcAIDocumentIndexingServiceTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/MvcAIDocumentIndexingServiceTests.cs index b401462f..d6626240 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/MvcAIDocumentIndexingServiceTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/MvcAIDocumentIndexingServiceTests.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class MvcAIDocumentIndexingServiceTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/MvcCitationReferenceCollectorTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/MvcCitationReferenceCollectorTests.cs index c20e7d92..cd2c2bdf 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/MvcCitationReferenceCollectorTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/MvcCitationReferenceCollectorTests.cs @@ -6,7 +6,7 @@ using CrestApps.Core.Mvc.Web.Services; using Microsoft.Extensions.DependencyInjection; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class MvcCitationReferenceCollectorTests { @@ -70,4 +70,4 @@ public string ResolveLink(string referenceId, IDictionary metada return $"/articles/{referenceId}"; } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/MvcViewModelBindingTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/MvcViewModelBindingTests.cs index 60b4a991..ba1fdeb7 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/MvcViewModelBindingTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/MvcViewModelBindingTests.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.Rendering; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class MvcViewModelBindingTests { diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/SearchIndexProfileProvisioningServiceTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/SearchIndexProfileProvisioningServiceTests.cs index 84e93b31..8912ce34 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/SearchIndexProfileProvisioningServiceTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/SearchIndexProfileProvisioningServiceTests.cs @@ -14,7 +14,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class SearchIndexProfileProvisioningServiceTests { @@ -225,4 +225,4 @@ public ValueTask UpdateAsync(AIDeployment entry) return ValueTask.CompletedTask; } } -} \ No newline at end of file +} diff --git a/tests/CrestApps.Core.Tests/Framework/Mvc/YesSqlAIChatSessionManagerTests.cs b/tests/CrestApps.Core.Tests/Framework/Mvc/YesSqlAIChatSessionManagerTests.cs index 9b83ecb1..a7c5263b 100644 --- a/tests/CrestApps.Core.Tests/Framework/Mvc/YesSqlAIChatSessionManagerTests.cs +++ b/tests/CrestApps.Core.Tests/Framework/Mvc/YesSqlAIChatSessionManagerTests.cs @@ -10,7 +10,7 @@ using Microsoft.Extensions.Options; using Moq; -namespace CrestApps.OrchardCore.Tests.Framework.Mvc; +namespace CrestApps.Core.Tests.Framework.Mvc; public sealed class YesSqlAIChatSessionManagerTests { diff --git a/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/OpenXmlIngestionDocumentReaderTests.cs b/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/OpenXmlIngestionDocumentReaderTests.cs index 46c4736b..1a064b98 100644 --- a/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/OpenXmlIngestionDocumentReaderTests.cs +++ b/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/OpenXmlIngestionDocumentReaderTests.cs @@ -10,7 +10,7 @@ using WpRun = DocumentFormat.OpenXml.Wordprocessing.Run; using WpText = DocumentFormat.OpenXml.Wordprocessing.Text; -namespace CrestApps.OrchardCore.Tests.Helpers.DocumentReaders; +namespace CrestApps.Core.Tests.Helpers.DocumentReaders; public sealed class OpenXmlIngestionDocumentReaderTests { diff --git a/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/PdfIngestionDocumentReaderTests.cs b/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/PdfIngestionDocumentReaderTests.cs index 948b27a9..cae31039 100644 --- a/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/PdfIngestionDocumentReaderTests.cs +++ b/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/PdfIngestionDocumentReaderTests.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Http; using UglyToad.PdfPig.Writer; -namespace CrestApps.OrchardCore.Tests.Helpers.DocumentReaders; +namespace CrestApps.Core.Tests.Helpers.DocumentReaders; public sealed class PdfIngestionDocumentReaderTests { diff --git a/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/PlainTextIngestionDocumentReaderTests.cs b/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/PlainTextIngestionDocumentReaderTests.cs index 5176f065..a49322bb 100644 --- a/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/PlainTextIngestionDocumentReaderTests.cs +++ b/tests/CrestApps.Core.Tests/Helpers/DocumentReaders/PlainTextIngestionDocumentReaderTests.cs @@ -1,7 +1,7 @@ using System.Text; using CrestApps.Core.AI.Chat.Services; -namespace CrestApps.OrchardCore.Tests.Helpers.DocumentReaders; +namespace CrestApps.Core.Tests.Helpers.DocumentReaders; public sealed class PlainTextIngestionDocumentReaderTests { diff --git a/tests/CrestApps.Core.Tests/Mcp/McpConnectionDeploymentSanitizationTests.cs b/tests/CrestApps.Core.Tests/Mcp/McpConnectionDeploymentSanitizationTests.cs index 524cd733..b1d97e6d 100644 --- a/tests/CrestApps.Core.Tests/Mcp/McpConnectionDeploymentSanitizationTests.cs +++ b/tests/CrestApps.Core.Tests/Mcp/McpConnectionDeploymentSanitizationTests.cs @@ -4,7 +4,7 @@ using CrestApps.Core.AI.Mcp; using CrestApps.Core.AI.Mcp.Models; -namespace CrestApps.OrchardCore.Tests.Mcp; +namespace CrestApps.Core.Tests.Mcp; /// /// Tests that deployment export never leaks sensitive credential data. diff --git a/tests/CrestApps.Core.Tests/Mcp/SseClientTransportProviderTests.cs b/tests/CrestApps.Core.Tests/Mcp/SseClientTransportProviderTests.cs index fe1d780c..3d08e1a8 100644 --- a/tests/CrestApps.Core.Tests/Mcp/SseClientTransportProviderTests.cs +++ b/tests/CrestApps.Core.Tests/Mcp/SseClientTransportProviderTests.cs @@ -8,7 +8,7 @@ using ModelContextProtocol.Client; using Moq; -namespace CrestApps.OrchardCore.Tests.Mcp; +namespace CrestApps.Core.Tests.Mcp; public sealed class SseClientTransportProviderTests { diff --git a/tests/CrestApps.Core.Tests/Modules/AI.Memory/Handlers/AIMemoryOrchestrationContextHelperTests.cs b/tests/CrestApps.Core.Tests/Modules/AI.Memory/Handlers/AIMemoryOrchestrationContextHelperTests.cs index e40e21df..e3f6505e 100644 --- a/tests/CrestApps.Core.Tests/Modules/AI.Memory/Handlers/AIMemoryOrchestrationContextHelperTests.cs +++ b/tests/CrestApps.Core.Tests/Modules/AI.Memory/Handlers/AIMemoryOrchestrationContextHelperTests.cs @@ -2,7 +2,7 @@ using CrestApps.Core.AI.Handlers; using Microsoft.AspNetCore.Http; -namespace CrestApps.OrchardCore.Tests.Modules.AI.Memory.Handlers; +namespace CrestApps.Core.Tests.Modules.AI.Memory.Handlers; public sealed class AIMemoryOrchestrationContextHelperTests { diff --git a/tests/CrestApps.Core.Tests/Modules/AI.Memory/Handlers/AIMemoryPreemptiveRagHandlerTests.cs b/tests/CrestApps.Core.Tests/Modules/AI.Memory/Handlers/AIMemoryPreemptiveRagHandlerTests.cs index 0905875c..a7ec63a7 100644 --- a/tests/CrestApps.Core.Tests/Modules/AI.Memory/Handlers/AIMemoryPreemptiveRagHandlerTests.cs +++ b/tests/CrestApps.Core.Tests/Modules/AI.Memory/Handlers/AIMemoryPreemptiveRagHandlerTests.cs @@ -11,7 +11,7 @@ #pragma warning disable MEAI001 -namespace CrestApps.OrchardCore.Tests.Modules.AI.Memory.Handlers; +namespace CrestApps.Core.Tests.Modules.AI.Memory.Handlers; public sealed class AIMemoryPreemptiveRagHandlerTests { diff --git a/tests/CrestApps.Core.Tests/Modules/AI.Memory/Services/DefaultAIMemorySafetyServiceTests.cs b/tests/CrestApps.Core.Tests/Modules/AI.Memory/Services/DefaultAIMemorySafetyServiceTests.cs index 133e8243..9c8c2e13 100644 --- a/tests/CrestApps.Core.Tests/Modules/AI.Memory/Services/DefaultAIMemorySafetyServiceTests.cs +++ b/tests/CrestApps.Core.Tests/Modules/AI.Memory/Services/DefaultAIMemorySafetyServiceTests.cs @@ -1,6 +1,6 @@ using CrestApps.Core.AI.Services; -namespace CrestApps.OrchardCore.Tests.Modules.AI.Memory.Services; +namespace CrestApps.Core.Tests.Modules.AI.Memory.Services; public sealed class DefaultAIMemorySafetyServiceTests {